Jekyll2026-03-17T19:12:40+00:00https://bitcoinops.org/Bitcoin OptechHelping Bitcoin-based businesses integrate scaling technology.Bitcoin OptechBitcoin Optech Newsletter #396 Recap Podcast2026-03-17T00:00:00+00:002026-03-17T00:00:00+00:00https://bitcoinops.org/en/podcast/2026/03/2026-03-17-recap<p>Mark “Murch” Erhardt, Gustavo Flores Echaiz, and Mike Schmidt are joined by
Jonathan Harvey-Buschel to discuss
<a href="/en/newsletters/2026/03/13/">Newsletter #396</a>.</p>
<div id="podcast-links">
<a href="https://anchor.fm/s/d9918154/podcast/rss" title="Subscribe using RSS"><img src="/img/podcast/rss.png" alt="RSS icon" /></a>
<a href="https://podcasts.apple.com/us/podcast/bitcoin-optech-podcast/id1674626983" title="Subscribe using Apple Podcasts"><img src="/img/podcast/apple_podcasts.png" alt="Apple Podcasts icon" /></a>
<a href="https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9kOTkxODE1NC9wb2RjYXN0L3Jzcw" title="Subscribe using Google Podcasts"><img src="/img/podcast/google_podcasts.png" alt="Google Podcasts icon" /></a>
<a href="https://music.amazon.com/podcasts/d7540633-146f-4733-b716-4b38bafa8020/bitcoin-optech-podcast" title="Subscribe using Amazon Music"><img src="/img/podcast/amazon.png" alt="Amazon Music icon" /></a>
<a href="https://open.spotify.com/show/5UnB50h4O1jKaq5AyfN9Qo" title="Subscribe using Spotify"><img src="/img/podcast/spotify.png" alt="Spotify icon" /></a>
<a href="https://pca.st/tb9hbxoa" title="Subscribe using Pocket Casts"><img src="/img/podcast/pocket_casts.png" alt="Pocket Casts icon" /></a>
<a href="https://castbox.fm/channel/id5330863" title="Subscribe using Castbox"><img src="/img/podcast/castbox.png" alt="Castbox icon" /></a>
<a href="https://podcastindex.org/podcast/6071192" title="Listen on Podcast 2.0 players"><img src="/img/podcast/podcast-index.png" alt="Podcast Index icon" /></a>
<a href="https://anchor.fm/bitcoin-optech/" title="Listen on Anchor.fm"><img src="/img/podcast/anchor.png" alt="Anchor.fm icon" /></a>
</div>
<p><em>The Bitcoin Optech Podcast and transcription content is licensed Creative Commons <a href="https://creativecommons.org/licenses/by-sa/2.0/legalcode" target="_blank">CC BY-SA 2.0</a></em></p>
<audio id="player" controls="" type="audio/mpeg" src="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-2-17/420221497-44100-2-6ec15cadb2353.m4a">
<a href="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-2-17/420221497-44100-2-6ec15cadb2353.m4a">
Download audio
</a>
</audio>
<div>
<h2 id="news"> News
</h2>
<ul>
<li id="collision-resistant-hash-function-for-bitcoin-script" class="anchor-list">
<p>
<a href="#collision-resistant-hash-function-for-bitcoin-script" class="anchor-list-link">●</a>
Collision-resistant hash function for Bitcoin Script
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('0:30')" class="seek">0:30</a><noscript>0:30</noscript>)
<a href="/en/newsletters/2026/03/13/#collision-resistant-hash-function-for-bitcoin-script">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="continued-discussion-of-gossip-observer-traffic-analysis-tool" class="anchor-list">
<p>
<a href="#continued-discussion-of-gossip-observer-traffic-analysis-tool" class="anchor-list-link">●</a>
Continued discussion of Gossip Observer traffic analysis tool
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('8:58')" class="seek">8:58</a><noscript>8:58</noscript>)
<a href="/en/newsletters/2026/03/13/#continued-discussion-of-gossip-observer-traffic-analysis-tool">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
<h2 id="releases-and-release-candidates"> Releases and release candidates
</h2>
<ul>
<li id="bdk-wallet-3-0-0-rc-1" class="anchor-list">
<p>
<a href="#bdk-wallet-3-0-0-rc-1" class="anchor-list-link">●</a>
BDK wallet 3.0.0-rc.1
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('28:04')" class="seek">28:04</a><noscript>28:04</noscript>)
<a href="/en/newsletters/2026/03/13/#bdk-wallet-3-0-0-rc-1">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes"> Notable code and documentation changes
</h2>
<ul>
<li id="bitcoin-core-26988" class="anchor-list">
<p>
<a href="#bitcoin-core-26988" class="anchor-list-link">●</a>
Bitcoin Core #26988
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('30:39')" class="seek">30:39</a><noscript>30:39</noscript>)
<a href="/en/newsletters/2026/03/13/#bitcoin-core-26988">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bitcoin-core-34692" class="anchor-list">
<p>
<a href="#bitcoin-core-34692" class="anchor-list-link">●</a>
Bitcoin Core #34692
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('32:22')" class="seek">32:22</a><noscript>32:22</noscript>)
<a href="/en/newsletters/2026/03/13/#bitcoin-core-34692">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="ldk-4304" class="anchor-list">
<p>
<a href="#ldk-4304" class="anchor-list-link">●</a>
LDK #4304
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('33:21')" class="seek">33:21</a><noscript>33:21</noscript>)
<a href="/en/newsletters/2026/03/13/#ldk-4304">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="ldk-4416" class="anchor-list">
<p>
<a href="#ldk-4416" class="anchor-list-link">●</a>
LDK #4416
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('35:41')" class="seek">35:41</a><noscript>35:41</noscript>)
<a href="/en/newsletters/2026/03/13/#ldk-4416">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="lnd-10089" class="anchor-list">
<p>
<a href="#lnd-10089" class="anchor-list-link">●</a>
LND #10089
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('38:01')" class="seek">38:01</a><noscript>38:01</noscript>)
<a href="/en/newsletters/2026/03/13/#lnd-10089">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="libsecp256k1-1777" class="anchor-list">
<p>
<a href="#libsecp256k1-1777" class="anchor-list-link">●</a>
Libsecp256k1 #1777
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('39:46')" class="seek">39:46</a><noscript>39:46</noscript>)
<a href="/en/newsletters/2026/03/13/#libsecp256k1-1777">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bips-2047" class="anchor-list">
<p>
<a href="#bips-2047" class="anchor-list-link">●</a>
BIPs #2047
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('42:39')" class="seek">42:39</a><noscript>42:39</noscript>)
<a href="/en/newsletters/2026/03/13/#bips-2047">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bolts-1316" class="anchor-list">
<p>
<a href="#bolts-1316" class="anchor-list-link">●</a>
BOLTs #1316
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('46:42')" class="seek">46:42</a><noscript>46:42</noscript>)
<a href="/en/newsletters/2026/03/13/#bolts-1316">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bolts-1312" class="anchor-list">
<p>
<a href="#bolts-1312" class="anchor-list-link">●</a>
BOLTs #1312
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('47:26')" class="seek">47:26</a><noscript>47:26</noscript>)
<a href="/en/newsletters/2026/03/13/#bolts-1312">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
</div>
<h2 id="transcription">Transcription</h2>
<p><em>transcription coming soon</em></p>Bitcoin OptechMark “Murch” Erhardt, Gustavo Flores Echaiz, and Mike Schmidt are joined by Jonathan Harvey-Buschel to discuss Newsletter #396.Bitcoin Optech Newsletter #3962026-03-13T00:00:00+00:002026-03-13T00:00:00+00:00https://bitcoinops.org/en/newsletters/2026/03/2026-03-13-newsletter<p>This week’s newsletter describes a collision-resistant hash function using
Bitcoin Script and summarizes continued discussion of Lightning Network traffic
analysis. Also included are our regular sections with announcements of new releases
and release candidates and descriptions of notable changes to popular Bitcoin
infrastructure software.</p>
<h2 id="news">News</h2>
<ul>
<li id="collision-resistant-hash-function-for-bitcoin-script" class="anchor-list">
<p><a href="#collision-resistant-hash-function-for-bitcoin-script" class="anchor-list-link">●</a> <strong>Collision-resistant hash function for Bitcoin Script</strong>: Robin Linus
<a href="https://delvingbitcoin.org/t/binohash-transaction-introspection-without-softforks/2288">posted</a> to Delving Bitcoin about Binohash, a new collision-resistant hash
function using Bitcoin Script. In the <a href="https://robinlinus.com/binohash.pdf">paper</a> he shared, Linus states that
Binohash allows for limited transaction introspection without requiring new consensus
changes. In turn, this enables protocols like <a href="/en/topics/acc/">BitVM</a> bridges with
<a href="/en/topics/covenants/">covenant</a>-like functionalities for trustless introspection, without the need to
rely on trusted oracles.</p>
<p>The proposed hash function indirectly derives a transaction digest following a
two-step process:</p>
<ul>
<li>
<p>Pin transaction fields: Transaction fields are bound by requiring a spender
to solve multiple signature puzzles, each demanding <code class="language-plaintext highlighter-rouge">W1</code> bits of work, making
unauthorized modification computationally expensive.</p>
</li>
<li>
<p>Derive the hash: The hash is computed by leveraging the behavior of
<code class="language-plaintext highlighter-rouge">FindAndDelete</code> in legacy <code class="language-plaintext highlighter-rouge">OP_CHECKMULTISIG</code>. A nonce pool is initialized
with <code class="language-plaintext highlighter-rouge">n</code> signatures. A spender produces a subset with <code class="language-plaintext highlighter-rouge">t</code> signatures, which are
removed from the pool using <code class="language-plaintext highlighter-rouge">FindAndDelete</code>, and then computes a sighash of the
remaining signatures. The process is iterated until a sighash produces a puzzle
signature matching requirements. The resulting digest, the Binohash, will be composed of the <code class="language-plaintext highlighter-rouge">t</code> indices of the winning subset.</p>
</li>
</ul>
<p>The output digest has three properties relevant to Bitcoin applications: it
can be extracted and verified entirely within Bitcoin Script; it provides
approximately 84 bits of collision resistance; and it is <a href="https://en.wikipedia.org/wiki/Lamport_signature">Lamport-signable</a>,
allowing it to be committed to inside a BitVM program. Together these
properties mean developers can construct protocols that reason about
transaction data on-chain today, using only existing script primitives. <a href="/en/podcast/2026/03/17/#collision-resistant-hash-function-for-bitcoin-script"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="continued-discussion-of-gossip-observer-traffic-analysis-tool" class="anchor-list">
<p><a href="#continued-discussion-of-gossip-observer-traffic-analysis-tool" class="anchor-list-link">●</a> <strong>Continued discussion of Gossip Observer traffic analysis tool</strong>: In November, Jonathan
Harvey-Buschel <a href="/en/newsletters/2025/11/21/#ln-gossip-traffic-analysis-tool-announced">announced</a> Gossip Observer, a tool
for collecting LN gossip traffic and computing metrics to evaluate replacing
message flooding with a set-reconciliation-based protocol.</p>
<p>Since then, Rusty Russell and others <a href="https://delvingbitcoin.org/t/gossip-observer-new-project-to-monitor-the-lightning-p2p-network/2105">joined the discussion</a> on how best to transmit sketches. Russell suggested encoding
improvements for efficiency, including skipping the <code class="language-plaintext highlighter-rouge">GETDATA</code> round-trip by
using the block number suffix as the set key for a message, avoiding an
unnecessary request/response exchange when the receiver can already infer the
relevant block context.</p>
<p>In response, Harvey-Buschel <a href="https://github.com/jharveyb/gossip_observer">updated</a> his version of
Gossip Observer that is running and continuing to collect data. He
<a href="https://delvingbitcoin.org/t/gossip-observer-new-project-to-monitor-the-lightning-p2p-network/2105/23">posted</a> analysis of average daily messages, a model of
detected communities, and propagation delays. <a href="/en/podcast/2026/03/17/#continued-discussion-of-gossip-observer-traffic-analysis-tool"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="releases-and-release-candidates">Releases and release candidates</h2>
<p><em>New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.</em></p>
<ul>
<li id="bdk-wallet-3-0-0-rc-1" class="anchor-list"><a href="#bdk-wallet-3-0-0-rc-1" class="anchor-list-link">●</a> <a href="https://github.com/bitcoindevkit/bdk_wallet/releases/tag/v3.0.0-rc.1">BDK wallet 3.0.0-rc.1</a> is a release candidate for a new major
version of this library for building wallet applications. Major
changes include UTXO locking that persists across restarts, structured
wallet events returned on chain updates, and adoption of <code class="language-plaintext highlighter-rouge">NetworkKind</code>
throughout the API to distinguish mainnet from testnet. The release
also adds Caravan (see <a href="/en/newsletters/2019/12/18/#unchained-capital-open-sources-caravan-a-multisig-coordinator">Newsletter #77</a>) wallet format
import/export and a migration utility for SQLite databases from before
version 1.0. <a href="/en/podcast/2026/03/17/#bdk-wallet-3-0-0-rc-1"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></li>
</ul>
<h2 id="notable-code-and-documentation-changes">Notable code and documentation changes</h2>
<p><em>Notable recent changes in <a href="https://github.com/bitcoin/bitcoin">Bitcoin Core</a>, <a href="https://github.com/ElementsProject/lightning">Core
Lightning</a>, <a href="https://github.com/ACINQ/eclair">Eclair</a>, <a href="https://github.com/lightningdevkit/rust-lightning">LDK</a>,
<a href="https://github.com/lightningnetwork/lnd/">LND</a>, <a href="https://github.com/bitcoin-core/secp256k1">libsecp256k1</a>, <a href="https://github.com/bitcoin-core/HWI">Hardware Wallet
Interface (HWI)</a>, <a href="https://github.com/rust-bitcoin/rust-bitcoin">Rust Bitcoin</a>, <a href="https://github.com/btcpayserver/btcpayserver/">BTCPay
Server</a>, <a href="https://github.com/bitcoindevkit/bdk">BDK</a>, <a href="https://github.com/bitcoin/bips/">Bitcoin Improvement
Proposals (BIPs)</a>, <a href="https://github.com/lightning/bolts">Lightning BOLTs</a>,
<a href="https://github.com/lightning/blips">Lightning BLIPs</a>, <a href="https://github.com/bitcoin-inquisition/bitcoin">Bitcoin Inquisition</a>, and <a href="https://github.com/bitcoin-inquisition/binana">BINANAs</a>.</em></p>
<ul>
<li id="bitcoin-core-26988" class="anchor-list">
<p><a href="#bitcoin-core-26988" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/26988">Bitcoin Core #26988</a> updates the <code class="language-plaintext highlighter-rouge">-addrinfo</code> CLI command (see
<a href="/en/newsletters/2021/04/28/#bitcoin-core-21595">Newsletter #146</a>) to now return the full set of
known addresses, instead of a subset filtered for quality and recency.
Internally, the <code class="language-plaintext highlighter-rouge">getaddrmaninfo</code> RPC (see <a href="/en/newsletters/2023/11/01/#bitcoin-core-28565">Newsletter #275</a>) is used instead of the <code class="language-plaintext highlighter-rouge">getnodeaddresses</code> RPC (see
<a href="/en/newsletters/2018/09/25/#bitcoin-core-13152">Newsletter #14</a>). The returned count now matches the
unfiltered set used to select outbound peers. <a href="/en/podcast/2026/03/17/#bitcoin-core-26988"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-34692" class="anchor-list">
<p><a href="#bitcoin-core-34692" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/34692">Bitcoin Core #34692</a> increases the default <code class="language-plaintext highlighter-rouge">dbcache</code> from 450 MiB
to 1 GiB on 64-bit systems with at least 4 GiB of RAM, falling back
to 450 MiB otherwise. This change only affects <code class="language-plaintext highlighter-rouge">bitcoind</code>; the kernel
library retains 450 MiB as its default. <a href="/en/podcast/2026/03/17/#bitcoin-core-34692"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4304" class="anchor-list">
<p><a href="#ldk-4304" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4304">LDK #4304</a> refactors <a href="/en/topics/htlc/">HTLC</a> forwarding to support
multiple incoming and outgoing HTLCs per forward, laying the
groundwork for <a href="/en/topics/trampoline-payments/">trampoline</a> routing. Unlike
regular forwarding, a trampoline node can act as an <a href="/en/topics/multipath-payments/">MPP</a> endpoint on both sides: it accumulates incoming
HTLC parts, finds routes to the next hop, and splits the forward
across multiple outgoing HTLCs. A new <code class="language-plaintext highlighter-rouge">HTLCSource::TrampolineForward</code>
variant tracks all HTLCs for a trampoline forward. Claims and failures
are handled properly, and channel monitor recovery is extended to
reconstruct the trampoline forward state upon restart. <a href="/en/podcast/2026/03/17/#ldk-4304"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4416" class="anchor-list">
<p><a href="#ldk-4416" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4416">LDK #4416</a> enables an acceptor to contribute funds when both peers
attempt to initiate a <a href="/en/topics/splicing/">splice</a> simultaneously,
effectively adding support for <a href="/en/topics/dual-funding/">dual funding</a> on
splices. When both sides initiate, <a href="/en/topics/channel-commitment-upgrades/">quiescence</a> tie-breaking selects one as the initiator.
Previously, only the initiator could add funds, and the acceptor had
to wait for a subsequent splice to add their own. Since the acceptor
had prepared to be the initiator, their fee is adjusted from the
initiator rate (which covers common transaction fields) to the
acceptor rate. The <code class="language-plaintext highlighter-rouge">splice_channel</code> API now also accepts a
<code class="language-plaintext highlighter-rouge">max_feerate</code> parameter to target a maximum feerate. <a href="/en/podcast/2026/03/17/#ldk-4416"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="lnd-10089" class="anchor-list">
<p><a href="#lnd-10089" class="anchor-list-link">●</a> <a href="https://github.com/lightningnetwork/lnd/issues/10089">LND #10089</a> adds <a href="/en/topics/onion-messages/">onion message</a> forwarding
support, building on the message types and RPCs from <a href="/en/newsletters/2025/10/24/#lnd-9868">Newsletter
#377</a>. It introduces an <code class="language-plaintext highlighter-rouge">OnionMessagePayload</code> wire type
to decode the onion’s inner payload, and a per-peer actor that handles
decryption and forwarding decisions. The feature can be disabled using
the <code class="language-plaintext highlighter-rouge">--protocol.no-onion-messages</code> flag. This is part of LND’s
roadmap toward <a href="/en/topics/offers/">BOLT12 offers</a> support. <a href="/en/podcast/2026/03/17/#lnd-10089"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="libsecp256k1-1777" class="anchor-list">
<p><a href="#libsecp256k1-1777" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin-core/secp256k1/issues/1777">Libsecp256k1 #1777</a> adds a new
<code class="language-plaintext highlighter-rouge">secp256k1_context_set_sha256_compression()</code> API, which allows
applications to supply a custom SHA256 compression function at
runtime. This API allows environments such as Bitcoin Core, which
already detect CPU features at startup, to route libsecp256k1’s
hashing through hardware-accelerated SHA256 without recompiling the
library. <a href="/en/podcast/2026/03/17/#libsecp256k1-1777"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-2047" class="anchor-list">
<p><a href="#bips-2047" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/2047">BIPs #2047</a> publishes <a href="https://github.com/bitcoin/bips/blob/master/bip-0392.mediawiki">BIP392</a>, which defines a
<a href="/en/topics/output-script-descriptors/">descriptor</a> format for <a href="/en/topics/silent-payments/">silent payment</a> wallets. The new <code class="language-plaintext highlighter-rouge">sp()</code> descriptor instructs wallet
software on how to scan for and spend silent payment outputs, which
are <a href="/en/topics/taproot/">P2TR</a> outputs as specified in <a href="https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki">BIP352</a>. A one
key expression argument form takes a single <a href="/en/topics/bech32/">bech32m</a>
key: <code class="language-plaintext highlighter-rouge">spscan</code> which encodes the scan private key and the spend public
key for watch-only, or <code class="language-plaintext highlighter-rouge">spspend</code> which encodes both scan and spend
private keys. A two-argument form <code class="language-plaintext highlighter-rouge">sp(KEY,KEY)</code> takes a private scan
key as first expression and a separate spend key expression, either
public or private with support for <a href="/en/topics/musig/">MuSig2</a> aggregate
keys via <a href="https://github.com/bitcoin/bips/blob/master/bip-0390.mediawiki">BIP390</a>. See <a href="/en/newsletters/2026/01/09/#draft-bip-for-silent-payment-descriptors">Newsletter #387</a> for the
initial mailing list discussion. <a href="/en/podcast/2026/03/17/#bips-2047"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bolts-1316" class="anchor-list">
<p><a href="#bolts-1316" class="anchor-list-link">●</a> <a href="https://github.com/lightning/bolts/issues/1316">BOLTs #1316</a> clarifies that <code class="language-plaintext highlighter-rouge">offer_amount</code> in <a href="/en/topics/offers/">BOLT12 offers</a> must be greater than zero when present. Writers must set the
<code class="language-plaintext highlighter-rouge">offer_amount</code> to a value greater than zero, and readers must not
respond to offers where the amount is zero. Test vectors for invalid
zero-amount offers are added. <a href="/en/podcast/2026/03/17/#bolts-1316"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bolts-1312" class="anchor-list">
<p><a href="#bolts-1312" class="anchor-list-link">●</a> <a href="https://github.com/lightning/bolts/issues/1312">BOLTs #1312</a> adds a test vector for <a href="/en/topics/offers/">BOLT12</a> offers
with invalid <a href="/en/topics/bech32/">bech32</a> padding, clarifying that such
offers must be rejected according to <a href="https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki">BIP173</a> rules. This issue was
discovered through differential fuzzing across Lightning
implementations, which revealed that CLN and LDK accepted offers with
invalid padding while Eclair and Lightning-KMP correctly rejected
them. See <a href="/en/newsletters/2026/01/30/#ldk-4349">Newsletter #390</a> for LDK’s fix. <a href="/en/podcast/2026/03/17/#bolts-1312"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>Bitcoin OptechThis week’s newsletter describes a collision-resistant hash function using Bitcoin Script and summarizes continued discussion of Lightning Network traffic analysis. Also included are our regular sections with announcements of new releases and release candidates and descriptions of notable changes to popular Bitcoin infrastructure software.Bitcoin Optech Newsletter #395 Recap Podcast2026-03-10T00:00:00+00:002026-03-10T00:00:00+00:00https://bitcoinops.org/en/podcast/2026/03/2026-03-10-recap<p>Mark “Murch” Erhardt, Gustavo Flores Echaiz, and Mike Schmidt are joined by
Jon McAlpine, Antoine Poinsot, Mike Casey, and Ethan Heilman to discuss
<a href="/en/newsletters/2026/03/06/">Newsletter #395</a>.</p>
<div id="podcast-links">
<a href="https://anchor.fm/s/d9918154/podcast/rss" title="Subscribe using RSS"><img src="/img/podcast/rss.png" alt="RSS icon" /></a>
<a href="https://podcasts.apple.com/us/podcast/bitcoin-optech-podcast/id1674626983" title="Subscribe using Apple Podcasts"><img src="/img/podcast/apple_podcasts.png" alt="Apple Podcasts icon" /></a>
<a href="https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9kOTkxODE1NC9wb2RjYXN0L3Jzcw" title="Subscribe using Google Podcasts"><img src="/img/podcast/google_podcasts.png" alt="Google Podcasts icon" /></a>
<a href="https://music.amazon.com/podcasts/d7540633-146f-4733-b716-4b38bafa8020/bitcoin-optech-podcast" title="Subscribe using Amazon Music"><img src="/img/podcast/amazon.png" alt="Amazon Music icon" /></a>
<a href="https://open.spotify.com/show/5UnB50h4O1jKaq5AyfN9Qo" title="Subscribe using Spotify"><img src="/img/podcast/spotify.png" alt="Spotify icon" /></a>
<a href="https://pca.st/tb9hbxoa" title="Subscribe using Pocket Casts"><img src="/img/podcast/pocket_casts.png" alt="Pocket Casts icon" /></a>
<a href="https://castbox.fm/channel/id5330863" title="Subscribe using Castbox"><img src="/img/podcast/castbox.png" alt="Castbox icon" /></a>
<a href="https://podcastindex.org/podcast/6071192" title="Listen on Podcast 2.0 players"><img src="/img/podcast/podcast-index.png" alt="Podcast Index icon" /></a>
<a href="https://anchor.fm/bitcoin-optech/" title="Listen on Anchor.fm"><img src="/img/podcast/anchor.png" alt="Anchor.fm icon" /></a>
</div>
<p><em>The Bitcoin Optech Podcast and transcription content is licensed Creative Commons <a href="https://creativecommons.org/licenses/by-sa/2.0/legalcode" target="_blank">CC BY-SA 2.0</a></em></p>
<audio id="player" controls="" type="audio/mpeg" src="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-2-11/419798504-44100-2-31bff5b4caf7f.m4a">
<a href="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-2-11/419798504-44100-2-31bff5b4caf7f.m4a">
Download audio
</a>
</audio>
<div>
<h2 id="news"> News
</h2>
<ul>
<li id="a-standard-for-stateless-vtxo-verification" class="anchor-list">
<p>
<a href="#a-standard-for-stateless-vtxo-verification" class="anchor-list-link">●</a>
A standard for stateless VTXO verification
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:31')" class="seek">1:31</a><noscript>1:31</noscript>)
<a href="/en/newsletters/2026/03/06/#a-standard-for-stateless-vtxo-verification">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="draft-bip-for-expanded-nversion-nonce-space-for-miners" class="anchor-list">
<p>
<a href="#draft-bip-for-expanded-nversion-nonce-space-for-miners" class="anchor-list-link">●</a>
Draft BIP for expanded `nVersion` nonce space for miners
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:23:45')" class="seek">1:23:45</a><noscript>1:23:45</noscript>)
<a href="/en/newsletters/2026/03/06/#draft-bip-for-expanded-nversion-nonce-space-for-miners">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
<h2 id="changing-consensus"> Changing consensus
</h2>
<ul>
<li id="extensions-to-standard-tooling-for-templatehash-csfs-ik-support" class="anchor-list">
<p>
<a href="#extensions-to-standard-tooling-for-templatehash-csfs-ik-support" class="anchor-list-link">●</a>
Extensions to standard tooling for TEMPLATEHASH-CSFS-IK support
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('13:52')" class="seek">13:52</a><noscript>13:52</noscript>)
<a href="/en/newsletters/2026/03/06/#extensions-to-standard-tooling-for-templatehash-csfs-ik-support">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="hourglass-v2-update" class="anchor-list">
<p>
<a href="#hourglass-v2-update" class="anchor-list-link">●</a>
Hourglass V2 update
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('25:40')" class="seek">25:40</a><noscript>25:40</noscript>)
<a href="/en/newsletters/2026/03/06/#hourglass-v2-update">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="algorithm-agility-for-bitcoin" class="anchor-list">
<p>
<a href="#algorithm-agility-for-bitcoin" class="anchor-list-link">●</a>
Algorithm agility for Bitcoin
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('51:15')" class="seek">51:15</a><noscript>51:15</noscript>)
<a href="/en/newsletters/2026/03/06/#algorithm-agility-for-bitcoin">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="the-limitations-of-cryptographic-agility-in-bitcoin" class="anchor-list">
<p>
<a href="#the-limitations-of-cryptographic-agility-in-bitcoin" class="anchor-list-link">●</a>
The limitations of cryptographic agility in Bitcoin
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:05:15')" class="seek">1:05:15</a><noscript>1:05:15</noscript>)
<a href="/en/newsletters/2026/03/06/#the-limitations-of-cryptographic-agility-in-bitcoin">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
<h2 id="releases-and-release-candidates"> Releases and release candidates
</h2>
<ul>
<li id="bitcoin-core-28-4rc1" class="anchor-list">
<p>
<a href="#bitcoin-core-28-4rc1" class="anchor-list-link">●</a>
Bitcoin Core 28.4rc1
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:36:53')" class="seek">1:36:53</a><noscript>1:36:53</noscript>)
<a href="/en/newsletters/2026/03/06/#bitcoin-core-28-4rc1">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes"> Notable code and documentation changes
</h2>
<ul>
<li id="bitcoin-core-33616" class="anchor-list">
<p>
<a href="#bitcoin-core-33616" class="anchor-list-link">●</a>
Bitcoin Core #33616
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:38:30')" class="seek">1:38:30</a><noscript>1:38:30</noscript>)
<a href="/en/newsletters/2026/03/06/#bitcoin-core-33616">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bitcoin-core-34616" class="anchor-list">
<p>
<a href="#bitcoin-core-34616" class="anchor-list-link">●</a>
Bitcoin Core #34616
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:42:23')" class="seek">1:42:23</a><noscript>1:42:23</noscript>)
<a href="/en/newsletters/2026/03/06/#bitcoin-core-34616">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="eclair-3256" class="anchor-list">
<p>
<a href="#eclair-3256" class="anchor-list-link">●</a>
Eclair #3256
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:46:20')" class="seek">1:46:20</a><noscript>1:46:20</noscript>)
<a href="/en/newsletters/2026/03/06/#eclair-3256">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="eclair-3258" class="anchor-list">
<p>
<a href="#eclair-3258" class="anchor-list-link">●</a>
Eclair #3258
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:48:34')" class="seek">1:48:34</a><noscript>1:48:34</noscript>)
<a href="/en/newsletters/2026/03/06/#eclair-3258">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="eclair-3255" class="anchor-list">
<p>
<a href="#eclair-3255" class="anchor-list-link">●</a>
Eclair #3255
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:50:14')" class="seek">1:50:14</a><noscript>1:50:14</noscript>)
<a href="/en/newsletters/2026/03/06/#eclair-3255">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="ldk-4402" class="anchor-list">
<p>
<a href="#ldk-4402" class="anchor-list-link">●</a>
LDK #4402
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:52:27')" class="seek">1:52:27</a><noscript>1:52:27</noscript>)
<a href="/en/newsletters/2026/03/06/#ldk-4402">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="lnd-10604" class="anchor-list">
<p>
<a href="#lnd-10604" class="anchor-list-link">●</a>
LND #10604
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:53:56')" class="seek">1:53:56</a><noscript>1:53:56</noscript>)
<a href="/en/newsletters/2026/03/06/#lnd-10604">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bips-1699" class="anchor-list">
<p>
<a href="#bips-1699" class="anchor-list-link">●</a>
BIPs #1699
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:55:34')" class="seek">1:55:34</a><noscript>1:55:34</noscript>)
<a href="/en/newsletters/2026/03/06/#bips-1699">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bips-2106" class="anchor-list">
<p>
<a href="#bips-2106" class="anchor-list-link">●</a>
BIPs #2106
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:57:30')" class="seek">1:57:30</a><noscript>1:57:30</noscript>)
<a href="/en/newsletters/2026/03/06/#bips-2106">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bips-2068" class="anchor-list">
<p>
<a href="#bips-2068" class="anchor-list-link">●</a>
BIPs #2068
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('2:01:28')" class="seek">2:01:28</a><noscript>2:01:28</noscript>)
<a href="/en/newsletters/2026/03/06/#bips-2068">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
<li id="bolts-1301" class="anchor-list">
<p>
<a href="#bolts-1301" class="anchor-list-link">●</a>
BOLTs #1301
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('2:04:54')" class="seek">2:04:54</a><noscript>2:04:54</noscript>)
<a href="/en/newsletters/2026/03/06/#bolts-1301">
<i class="fa fa-link" title="Link to related content"></i>
</a>
</p>
</li>
</ul>
</div>
<h2 id="transcription">Transcription</h2>
<p><em>transcription coming soon</em></p>Bitcoin OptechMark “Murch” Erhardt, Gustavo Flores Echaiz, and Mike Schmidt are joined by Jon McAlpine, Antoine Poinsot, Mike Casey, and Ethan Heilman to discuss Newsletter #395.Bitcoin Optech Newsletter #3952026-03-06T00:00:00+00:002026-03-06T00:00:00+00:00https://bitcoinops.org/en/newsletters/2026/03/2026-03-06-newsletter<p>This week’s newsletter describes a standard for verifying VTXOs across different
Ark implementations and links to a draft BIP for expanding the miner-usable
nonce space in the block header’s <code class="language-plaintext highlighter-rouge">nVersion</code> field. Also included are our
regular sections with descriptions of discussions about changing consensus,
announcements of new releases and release candidates, and summaries of notable
changes to popular Bitcoin infrastructure software.</p>
<h2 id="news">News</h2>
<ul>
<li id="a-standard-for-stateless-vtxo-verification" class="anchor-list">
<p><a href="#a-standard-for-stateless-vtxo-verification" class="anchor-list-link">●</a> <strong>A standard for stateless VTXO verification</strong>: Jgmcalpine <a href="https://delvingbitcoin.org/t/stateless-vtxo-verification-decoupling-custody-from-implementation-specific-stacks/2267">posted</a>
to Delving Bitcoin about his proposal for V-PACK, a stateless <a href="/en/topics/ark/">VTXO</a> verification
standard, which aims to provide a mechanism to independently verify and visualize
VTXOs in the Ark ecosystem. The goal is to develop a lean verifier able to run on
embedded environments, such as hardware wallets, to allow auditing off-chain state and
maintaining an independent backup of the data required for unilateral exit.</p>
<p>In particular, V-PACK verifies that a unilateral exit path exists, by checking that
the merkle path leads to a valid on-chain anchor and that the transaction preimages
match the signatures. However, Second CEO, Steven Roose, pointed out that path
exclusivity (i.e. verifying that the Ark Service Provider (ASP) did not introduce a
backdoor) is not checked for, to which Jgmcalpine answered that the topic would be
given the highest priority in the roadmap.</p>
<p>Due to significant differences among Ark implementations
(specifically, Arkade and Bark), V-PACK proposes a Minimal Viable VTXO (MVV) schema
to allow translating from an implementation’s “dialect” to a common neutral format,
without the need for an embedded environment to import all the specific
implementation’s codebase.</p>
<p>The V-PACK implementation, <a href="https://github.com/jgmcalpine/libvpack-rs">libvpack-rs</a>, is open-source, and a
<a href="https://www.vtxopack.org/">live tool</a> to visualize VTXOs is available for testing. <a href="/en/podcast/2026/03/10/#a-standard-for-stateless-vtxo-verification"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="draft-bip-for-expanded-nversion-nonce-space-for-miners" class="anchor-list">
<p><a href="#draft-bip-for-expanded-nversion-nonce-space-for-miners" class="anchor-list-link">●</a> <strong>Draft BIP for expanded <code class="language-plaintext highlighter-rouge">nVersion</code> nonce space for miners</strong>: Matt Corallo
<a href="https://groups.google.com/g/bitcoindev/c/fCfbi8hy-AE">posted</a> to the Bitcoin-Dev mailing list a draft
BIP to increase the number of bits available in <code class="language-plaintext highlighter-rouge">nVersion</code>’s nonce space for
miners from 16 to 24. This will enable more possible block candidates for
header-only mining without relying on rolling <code class="language-plaintext highlighter-rouge">nTime</code> more often than once per
second and would supersede <a href="https://github.com/bitcoin/bips/blob/master/bip-0320.mediawiki">BIP320</a>.</p>
<p>The motivation for this change is that BIP320 previously defined 16 bits
of <code class="language-plaintext highlighter-rouge">nVersion</code> as additional nonce space, but it turns out
that mining devices have started using 7 bits from <code class="language-plaintext highlighter-rouge">nTime</code> for extra nonce space.
Given the limited utility of the additional <code class="language-plaintext highlighter-rouge">nVersion</code> bits for use in soft fork signaling,
this BIP draft suggests to instead use some of those signaling bits to expand the <code class="language-plaintext highlighter-rouge">nVersion</code> extra nonce space.</p>
<p>The rationale behind this is that providing additional nonce space for the
ASICs to roll without needing fresh work from the controller may simplify ASIC
design and it is preferable to do so in <code class="language-plaintext highlighter-rouge">nVersion</code> instead of <code class="language-plaintext highlighter-rouge">nTime</code>, which
can distort block timestamps. <a href="/en/podcast/2026/03/10/#draft-bip-for-expanded-nversion-nonce-space-for-miners"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="changing-consensus">Changing consensus</h2>
<p><em>A monthly section summarizing proposals and discussion about changing
Bitcoin’s consensus rules.</em></p>
<ul>
<li id="extensions-to-standard-tooling-for-templatehash-csfs-ik-support" class="anchor-list">
<p><a href="#extensions-to-standard-tooling-for-templatehash-csfs-ik-support" class="anchor-list-link">●</a> <strong>Extensions to standard tooling for TEMPLATEHASH-CSFS-IK support:</strong>
Antoine Poinsot <a href="https://groups.google.com/g/bitcoindev/c/xur01RZM_Zs">wrote</a> on the Bitcoin-Dev mailing list about his
preliminary work to integrate the <a href="/en/newsletters/2025/08/01/#taproot-native-op-templatehash-proposal">taproot-native <code class="language-plaintext highlighter-rouge">OP_TEMPLATEHASH</code>
soft fork proposal</a> into <a href="/en/topics/miniscript/">miniscript</a> and
<a href="/en/topics/psbt/">PSBTs</a>.</p>
<p>The new opcodes require some reconsideration of the miniscript properties
because they break the assumption that signatures and transaction
commitments are always done together. This work also emphasizes the
limitations of Script’s stack structure by requiring an <code class="language-plaintext highlighter-rouge">OP_SWAP</code> before
each <code class="language-plaintext highlighter-rouge">OP_CHECKSIGFROMSTACK</code> when used with miniscript without further
changes to the type system. Because <code class="language-plaintext highlighter-rouge">OP_CHECKSIGFROMSTACK</code> takes 3 arguments
with either the message or the key or both being computed by other script
fragments, there is no obviously superior argument order that avoids
<code class="language-plaintext highlighter-rouge">OP_SWAP</code> in most cases.</p>
<p>The modifications required for PSBTs are simpler, primarily a per-output
field to map <code class="language-plaintext highlighter-rouge">OP_TEMPLATEHASH</code> commitments to their full transactions for
verification by signers. <a href="/en/podcast/2026/03/10/#extensions-to-standard-tooling-for-templatehash-csfs-ik-support"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="hourglass-v2-update" class="anchor-list">
<p><a href="#hourglass-v2-update" class="anchor-list-link">●</a> <strong>Hourglass V2 update:</strong> Mike Casey <a href="https://groups.google.com/g/bitcoindev/c/0E1UyyQIUA0">posted</a> an update to
the Bitcoin-Dev mailing list for the <a href="https://github.com/cryptoquick/bips/blob/hourglass-v2/bip-hourglass-v2.mediawiki">Hourglass protocol</a> to
mitigate the market impact of <a href="/en/topics/quantum-resistance/">quantum</a> attacks against certain lost coins.
The earlier proposal was discussed <a href="https://groups.google.com/g/bitcoindev/c/zmg3U117aNc">here</a>. This soft fork
would restrict the total value of P2PK-locked Bitcoin that can be spent in a
single block to 1 spent output and 1 Bitcoin. These specific values are
somewhat arbitrary, but seemed to those responding to represent a reasonable
Schelling point for such a restriction. Those responding in favor of the
change focused on the potential economic consequences of a large number of
Bitcoin being sold by a quantum adversary. Those responding against it
argued that possession of secret keys to unlock some Bitcoin is the only way
the protocol can identify ownership and that even in the face of a break in
the underlying cryptographic security, the protocol should not apply
additional restrictions on coin ownership or movement. <a href="/en/podcast/2026/03/10/#hourglass-v2-update"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="algorithm-agility-for-bitcoin" class="anchor-list">
<p><a href="#algorithm-agility-for-bitcoin" class="anchor-list-link">●</a> <strong>Algorithm agility for Bitcoin:</strong> Ethan Heilman <a href="https://groups.google.com/g/bitcoindev/c/7jkVS1K9WLo">wrote</a> on
the Bitcoin-Dev mailing list regarding the potential need for <a href="https://datatracker.ietf.org/doc/html/rfc7696">RFC7696 Cryptographic
Algorithm Agility</a> in Bitcoin. Heilman proposes that a
cryptographic algorithm be made available in <a href="https://github.com/bitcoin/bips/pull/1670">BIP360</a> P2MR scripts which
is not intended for current spending, but instead serves as a fallback to
bridge between primary signing algorithms in the event that the current
secp256k1-based signing algorithm (or some later primary algorithm) becomes
insecure. The central idea is that if Bitcoin supports two simultaneous
signing algorithms, future breaks of either one need not be as high stakes
as the current discussions around a potential quantum break of secp256k1.</p>
<p>Other developers responded with discussions of various potential backup
signing algorithms that would be unlikely to break in Heilman’s 75-year time
horizon.</p>
<p>Also discussed was the question of whether BIP360 P2MR, or something that
looks more like <a href="/en/topics/taproot/">P2TR</a> but opts into the keyspend being later
disabled by soft fork is preferable. In P2MR, all spends are script spends
with either a lower cost primary signature mechanism or a higher cost
fallback being chosen among merkle leaves. In a P2TR variant, the primary
signature type is a lower cost key spend until it is disabled due to a
cryptographic break and only the fallback must be a merkle leaf. Heilman
suggested that cold storage users would prefer P2MR and hot wallets could
readily switch to a new output type as needed, making the keyspend with
script backup signature algorithm irrelevant for both major types of users. <a href="/en/podcast/2026/03/10/#algorithm-agility-for-bitcoin"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="the-limitations-of-cryptographic-agility-in-bitcoin" class="anchor-list">
<p><a href="#the-limitations-of-cryptographic-agility-in-bitcoin" class="anchor-list-link">●</a> <strong>The limitations of cryptographic agility in Bitcoin:</strong>
Pieter Wuille <a href="https://groups.google.com/g/bitcoindev/c/O6l3GUvyO7A">wrote</a> to the Bitcoin-Dev mailing list about the
limitations of the cryptographic agility mentioned in the previous item. Specifically, because Bitcoin,
like all money, is based on belief, if the ownership of Bitcoin is secured by
a multiple cryptographic systems, proponents of each scheme want their scheme to be
used universally and, importantly, do not want other schemes to be used
because they would weaken the fundamental invariant of ownership security.
Wuille posits that in the fullness of time, old signature schemes will need
to be disabled as part of the migration from one scheme to another.</p>
<p>Heilman <a href="https://groups.google.com/g/bitcoindev/c/O6l3GUvyO7A/m/OXmZ-PnVAwAJ">proposes</a> that because the secondary signing scheme
proposed for algorithm agility is much more costly than the current scheme
(and hopefully a future primary scheme), it would remain a backup and only
used for migrations when the primary scheme has been shown to be
sufficiently weakened, thus avoiding the need to disable the secondary
scheme after each migration to a new primary scheme.</p>
<p>John Light <a href="https://groups.google.com/g/bitcoindev/c/O6l3GUvyO7A/m/5GnsttP2AwAJ">takes</a> the opposite view from Wuille, claiming
that disabling old, even insecure, signing schemes is a greater threat to
the shared belief in Bitcoin’s ownership model than the coins still secured
by such insecure schemes being claimed by whomever breaks them. Essentially
claiming that the most important aspect of Bitcoin’s ownership model is the
indelibility of each locking script’s validity from the time it is created
until it is spent.</p>
<p>Conduition <a href="https://groups.google.com/g/bitcoindev/c/O6l3GUvyO7A/m/5y9GkeXVBAAJ">counters</a> Wuille’s preconditions by demonstrating
that (thanks to Script’s flexibility) users can require signatures from
multiple signing schemes to unlock their coins. This allows users to express
a wider set of security assumptions than those which gave rise to Wuille’s
conclusion that insecure schemes would need to be disabled and that users of
each scheme would want nearly nobody to use others.</p>
<p>The discussion continues with some clarifications but no firm conclusions as
to how Bitcoin can practically migrate from one cryptosystem to another
whether in response to a quantum adversary or any other reason. <a href="/en/podcast/2026/03/10/#the-limitations-of-cryptographic-agility-in-bitcoin"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="releases-and-release-candidates">Releases and release candidates</h2>
<p><em>New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.</em></p>
<ul>
<li id="bitcoin-core-28-4rc1" class="anchor-list"><a href="#bitcoin-core-28-4rc1" class="anchor-list-link">●</a> <a href="https://bitcoincore.org/bin/bitcoin-core-28.4/test.rc1/">Bitcoin Core 28.4rc1</a> is a release candidate for a maintenance release of a
previous major release series. It primarily contains wallet migration fixes
and removal of an unreliable DNS seed. <a href="/en/podcast/2026/03/10/#bitcoin-core-28-4rc1"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></li>
</ul>
<h2 id="notable-code-and-documentation-changes">Notable code and documentation changes</h2>
<p><em>Notable recent changes in <a href="https://github.com/bitcoin/bitcoin">Bitcoin Core</a>, <a href="https://github.com/ElementsProject/lightning">Core
Lightning</a>, <a href="https://github.com/ACINQ/eclair">Eclair</a>, <a href="https://github.com/lightningdevkit/rust-lightning">LDK</a>,
<a href="https://github.com/lightningnetwork/lnd/">LND</a>, <a href="https://github.com/bitcoin-core/secp256k1">libsecp256k1</a>, <a href="https://github.com/bitcoin-core/HWI">Hardware Wallet
Interface (HWI)</a>, <a href="https://github.com/rust-bitcoin/rust-bitcoin">Rust Bitcoin</a>, <a href="https://github.com/btcpayserver/btcpayserver/">BTCPay
Server</a>, <a href="https://github.com/bitcoindevkit/bdk">BDK</a>, <a href="https://github.com/bitcoin/bips/">Bitcoin Improvement
Proposals (BIPs)</a>, <a href="https://github.com/lightning/bolts">Lightning BOLTs</a>,
<a href="https://github.com/lightning/blips">Lightning BLIPs</a>, <a href="https://github.com/bitcoin-inquisition/bitcoin">Bitcoin Inquisition</a>, and <a href="https://github.com/bitcoin-inquisition/binana">BINANAs</a>.</em></p>
<ul>
<li id="bitcoin-core-33616" class="anchor-list">
<p><a href="#bitcoin-core-33616" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/33616">Bitcoin Core #33616</a> skips the <a href="/en/topics/ephemeral-anchors/">ephemeral dust</a> spend check (<code class="language-plaintext highlighter-rouge">CheckEphemeralSpends</code>) during block reorgs when
confirmed transactions re-enter the mempool. Previously, these
transactions would be rejected by relay policy because they’re brought
back individually rather than as a package. This follows the same
pattern as <a href="https://github.com/bitcoin/bitcoin/issues/33504">Bitcoin Core #33504</a> (see <a href="/en/newsletters/2025/10/10/#bitcoin-core-33504">Newsletter #375</a>), which skipped <a href="/en/topics/version-3-transaction-relay/">TRUC</a> topology
checks during reorgs for the same reason. <a href="/en/podcast/2026/03/10/#bitcoin-core-33616"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-34616" class="anchor-list">
<p><a href="#bitcoin-core-34616" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/34616">Bitcoin Core #34616</a> introduces a more accurate cost model for the
spanning-forest <a href="/en/topics/cluster-mempool/">cluster linearization</a> (SFL)
algorithm (see <a href="/en/newsletters/2026/01/02/#bitcoin-core-32545">Newsletter #386</a>), by using cost limits to
bound the amount of CPU time spent searching for an optimal
linearization of each cluster. The previous model only tracked one type
of internal operation, resulting in a poor correlation between the
reported cost and the actual CPU time spent. The new model tracks many
internal operations with weights calibrated from benchmarks across
diverse hardware, providing a much closer approximation of real time. <a href="/en/podcast/2026/03/10/#bitcoin-core-34616"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="eclair-3256" class="anchor-list">
<p><a href="#eclair-3256" class="anchor-list-link">●</a> <a href="https://github.com/ACINQ/eclair/issues/3256">Eclair #3256</a> adds a new <code class="language-plaintext highlighter-rouge">ChannelFundingCreated</code> event emitted when
a funding or <a href="/en/topics/splicing/">splice</a> transaction has been signed and
is ready to be published. This is particularly useful for single-funded
channels where the non-funding side has no opportunity to validate
inputs beforehand and may want to force-close before the channel
confirms. <a href="/en/podcast/2026/03/10/#eclair-3256"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="eclair-3258" class="anchor-list">
<p><a href="#eclair-3258" class="anchor-list-link">●</a> <a href="https://github.com/ACINQ/eclair/issues/3258">Eclair #3258</a> adds a <code class="language-plaintext highlighter-rouge">ValidateInteractiveTxPlugin</code> trait that
enables plugins to inspect and reject the remote peer’s inputs and
outputs in interactive transactions before signing. This applies to
<a href="/en/topics/dual-funding/">dual-funded</a> channel opens and <a href="/en/topics/splicing/">splices</a>, where both sides participate in transaction construction. <a href="/en/podcast/2026/03/10/#eclair-3258"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="eclair-3255" class="anchor-list">
<p><a href="#eclair-3255" class="anchor-list-link">●</a> <a href="https://github.com/ACINQ/eclair/issues/3255">Eclair #3255</a> fixes the automatic channel type selection introduced
in <a href="https://github.com/ACINQ/eclair/issues/3250">Eclair #3250</a> (see <a href="/en/newsletters/2026/02/27/#eclair-3250">Newsletter #394</a>) so
that it no longer includes <code class="language-plaintext highlighter-rouge">scid_alias</code> for public channels. Per the
BOLTs, <code class="language-plaintext highlighter-rouge">scid_alias</code> is only allowed for <a href="/en/topics/unannounced-channels/">private channels</a>. <a href="/en/podcast/2026/03/10/#eclair-3255"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4402" class="anchor-list">
<p><a href="#ldk-4402" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4402">LDK #4402</a> fixes the HTLC claim timer to use the actual HTLC CLTV
expiry rather than the value from the onion payload. For
<a href="/en/topics/trampoline-payments/">trampoline</a> payments where a node is both a
trampoline hop and the final recipient, the actual HTLC expiry is
higher than what the onion specifies, because the outer trampoline
route added its own <a href="/en/topics/cltv-expiry-delta/">CLTV delta</a>. Using the
onion value caused the node to set a tighter claim deadline than
necessary. <a href="/en/podcast/2026/03/10/#ldk-4402"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="lnd-10604" class="anchor-list">
<p><a href="#lnd-10604" class="anchor-list-link">●</a> <a href="https://github.com/lightningnetwork/lnd/issues/10604">LND #10604</a> adds a SQL backend (SQLite or Postgres) for LND’s
outgoing payments database, as an alternative to the existing bbolt
key-value (KV) store. This consolidation PR brings together several
sub-PRs, notably <a href="https://github.com/lightningnetwork/lnd/issues/10153">#10153</a> which introduced an abstract
payment store interface, <a href="https://github.com/lightningnetwork/lnd/issues/9147">#9147</a> which implemented the SQL
schema and core backend, and <a href="https://github.com/lightningnetwork/lnd/issues/10485">#10485</a> which added an
experimental KV-to-SQL data migration. LND added support for
PostgreSQL in <a href="/en/newsletters/2021/10/06/#lnd-5366">Newsletter #169</a> and SQLite in
<a href="/en/newsletters/2023/02/08/#lnd-7252">Newsletter #237</a>. <a href="/en/podcast/2026/03/10/#lnd-10604"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-1699" class="anchor-list">
<p><a href="#bips-1699" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/1699">BIPs #1699</a> publishes <a href="https://github.com/bitcoin/bips/blob/master/bip-0442.md">BIP442</a> specifying <code class="language-plaintext highlighter-rouge">OP_PAIRCOMMIT</code>, a new
<a href="/en/topics/tapscript/">tapscript</a> opcode that pops two elements off the
stack and pushes their tagged SHA256 hash. This provides
multi-commitment functionality similar to what <a href="/en/topics/op_cat/">OP_CAT</a>
enables but avoids enabling recursive <a href="/en/topics/covenants/">covenants</a>.
<code class="language-plaintext highlighter-rouge">OP_PAIRCOMMIT</code> is part of the <a href="/en/newsletters/2025/12/05/#lnhance-soft-fork">LNHANCE</a> soft fork
proposal alongside <a href="/en/topics/op_checktemplateverify/">OP_CHECKTEMPLATEVERIFY</a> (<a href="https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki">BIP119</a>),
<a href="/en/topics/op_checksigfromstack/">OP_CHECKSIGFROMSTACK</a> (<a href="https://github.com/bitcoin/bips/blob/master/bip-0348.md">BIP348</a>), and
OP_INTERNALKEY (<a href="https://github.com/bitcoin/bips/blob/master/bip-0349.md">BIP349</a>). See <a href="/en/newsletters/2024/11/22/#update-to-lnhance-proposal">Newsletter #330</a>
for the initial proposal. <a href="/en/podcast/2026/03/10/#bips-1699"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-2106" class="anchor-list">
<p><a href="#bips-2106" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/2106">BIPs #2106</a> updates <a href="https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki">BIP352</a> (<a href="/en/topics/silent-payments/">silent payments</a>) to introduce a per-group recipient limit of <code class="language-plaintext highlighter-rouge">K_max</code> = 2323,
mitigating worst-case scanning time from adversarial transactions (see
<a href="/en/newsletters/2026/02/13/#proposal-to-limit-the-number-of-per-group-silent-payment-recipients">Newsletter #392</a>). This limit caps the number of
outputs that a scanner must check per recipient group within a single
transaction. The value was originally proposed at 1000 but increased to
2323 to match the maximum number of <a href="/en/topics/taproot/">P2TR</a> outputs that
can fit in a standard-sized (100 kvB) transaction and to avoid
fingerprinting silent payment transactions. <a href="/en/podcast/2026/03/10/#bips-2106"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-2068" class="anchor-list">
<p><a href="#bips-2068" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/2068">BIPs #2068</a> publishes <a href="https://github.com/bitcoin/bips/blob/master/bip-0128.mediawiki">BIP128</a>, which specifies a standard JSON
format for storing timelock-recovery plans. A recovery plan consists of
two pre-signed transactions for recovering funds if the owner loses
access to their wallet: an alert transaction that consolidates the
wallet’s UTXOs to a single address, and a recovery transaction that
moves those funds to backup wallets after a relative <a href="/en/topics/timelocks/">timelock</a> of 2–388 days. If the alert transaction is broadcast
prematurely, the owner can simply spend from the alert address to
invalidate the recovery. <a href="/en/podcast/2026/03/10/#bips-2068"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bolts-1301" class="anchor-list">
<p><a href="#bolts-1301" class="anchor-list-link">●</a> <a href="https://github.com/lightning/bolts/issues/1301">BOLTs #1301</a> updates the specification to recommend a higher
<code class="language-plaintext highlighter-rouge">dust_limit_satoshis</code> for <a href="/en/topics/anchor-outputs/">anchor</a> channels.
With <code class="language-plaintext highlighter-rouge">option_anchors</code>, pre-signed HTLC transactions have zero fees,
so their cost is no longer factored into the dust calculation. This
means HTLC outputs that pass the dust check may still be
<a href="/en/topics/uneconomical-outputs/">uneconomical</a> to claim on-chain, since
spending them requires a second-stage transaction whose fee can exceed
the output’s value. The spec now recommends that nodes set a dust
limit that accounts for the cost of these second-stage transactions,
and that nodes accept values above Bitcoin Core’s standard dust
thresholds from their peers. <a href="/en/podcast/2026/03/10/#bolts-1301"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>Bitcoin OptechThis week’s newsletter describes a standard for verifying VTXOs across different Ark implementations and links to a draft BIP for expanding the miner-usable nonce space in the block header’s nVersion field. Also included are our regular sections with descriptions of discussions about changing consensus, announcements of new releases and release candidates, and summaries of notable changes to popular Bitcoin infrastructure software.Bitcoin Optech Newsletter #394 Recap Podcast2026-03-03T00:00:00+00:002026-03-03T00:00:00+00:00https://bitcoinops.org/en/podcast/2026/03/2026-03-03-recap<p>Mark “Murch” Erhardt and Mike Schmidt are joined by Craig Raw and Fabian Jahr to
discuss <a href="/en/newsletters/2026/02/27/">Newsletter #394</a>.</p>
<div id="podcast-links">
<a href="https://anchor.fm/s/d9918154/podcast/rss" title="Subscribe using RSS"><img src="/img/podcast/rss.png" alt="RSS icon" /></a>
<a href="https://podcasts.apple.com/us/podcast/bitcoin-optech-podcast/id1674626983" title="Subscribe using Apple Podcasts"><img src="/img/podcast/apple_podcasts.png" alt="Apple Podcasts icon" /></a>
<a href="https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9kOTkxODE1NC9wb2RjYXN0L3Jzcw" title="Subscribe using Google Podcasts"><img src="/img/podcast/google_podcasts.png" alt="Google Podcasts icon" /></a>
<a href="https://music.amazon.com/podcasts/d7540633-146f-4733-b716-4b38bafa8020/bitcoin-optech-podcast" title="Subscribe using Amazon Music"><img src="/img/podcast/amazon.png" alt="Amazon Music icon" /></a>
<a href="https://open.spotify.com/show/5UnB50h4O1jKaq5AyfN9Qo" title="Subscribe using Spotify"><img src="/img/podcast/spotify.png" alt="Spotify icon" /></a>
<a href="https://pca.st/tb9hbxoa" title="Subscribe using Pocket Casts"><img src="/img/podcast/pocket_casts.png" alt="Pocket Casts icon" /></a>
<a href="https://castbox.fm/channel/id5330863" title="Subscribe using Castbox"><img src="/img/podcast/castbox.png" alt="Castbox icon" /></a>
<a href="https://podcastindex.org/podcast/6071192" title="Listen on Podcast 2.0 players"><img src="/img/podcast/podcast-index.png" alt="Podcast Index icon" /></a>
<a href="https://anchor.fm/bitcoin-optech/" title="Listen on Anchor.fm"><img src="/img/podcast/anchor.png" alt="Anchor.fm icon" /></a>
</div>
<p><em>The Bitcoin Optech Podcast and transcription content is licensed Creative Commons <a href="https://creativecommons.org/licenses/by-sa/2.0/legalcode" target="_blank">CC BY-SA 2.0</a></em></p>
<audio id="player" controls="" type="audio/mpeg" src="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-2-3/419224492-44100-2-244e6f6437741.m4a">
<a href="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-2-3/419224492-44100-2-244e6f6437741.m4a">
Download audio
</a>
</audio>
<div>
<h2 id="news"> News
</h2>
<ul>
<li id="draft-bip-for-output-script-descriptor-annotations" class="anchor-list">
<p>
<a href="#draft-bip-for-output-script-descriptor-annotations" class="anchor-list-link">●</a>
Draft BIP for output script descriptor annotations
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:25')" class="seek">1:25</a><noscript>1:25</noscript>)
<a href="/en/newsletters/2026/02/27/#draft-bip-for-output-script-descriptor-annotations">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#draft-bip-for-output-script-descriptor-annotations-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="selected-q-a-from-bitcoin-stack-exchange"> Selected Q&A from Bitcoin Stack Exchange
</h2>
<ul>
<li id="is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic" class="anchor-list">
<p>
<a href="#is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic" class="anchor-list-link">●</a>
Is Bitcoin BIP324 v2 P2P transport distinguishable from random traffic?
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('35:16')" class="seek">35:16</a><noscript>35:16</noscript>)
<a href="/en/newsletters/2026/02/27/#is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block" class="anchor-list">
<p>
<a href="#what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block" class="anchor-list-link">●</a>
What if a miner just broadcasts the header and never gives the block?
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('39:53')" class="seek">39:53</a><noscript>39:53</noscript>)
<a href="/en/newsletters/2026/02/27/#what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="releases-and-release-candidates"> Releases and release candidates
</h2>
<ul>
<li id="bitcoin-core-28-4rc1" class="anchor-list">
<p>
<a href="#bitcoin-core-28-4rc1" class="anchor-list-link">●</a>
Bitcoin Core 28.4rc1
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('47:27')" class="seek">47:27</a><noscript>47:27</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-28-4rc1">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-28-4rc1-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="rust-bitcoin-0-33-0-beta" class="anchor-list">
<p>
<a href="#rust-bitcoin-0-33-0-beta" class="anchor-list-link">●</a>
Rust Bitcoin 0.33.0-beta
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('47:46')" class="seek">47:46</a><noscript>47:46</noscript>)
<a href="/en/newsletters/2026/02/27/#rust-bitcoin-0-33-0-beta">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#rust-bitcoin-0-33-0-beta-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes"> Notable code and documentation changes
</h2>
<ul>
<li id="bitcoin-core-34568" class="anchor-list">
<p>
<a href="#bitcoin-core-34568" class="anchor-list-link">●</a>
Bitcoin Core #34568
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('48:48')" class="seek">48:48</a><noscript>48:48</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-34568">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-34568-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-core-34184" class="anchor-list">
<p>
<a href="#bitcoin-core-34184" class="anchor-list-link">●</a>
Bitcoin Core #34184
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('50:37')" class="seek">50:37</a><noscript>50:37</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-34184">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-34184-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-core-24539" class="anchor-list">
<p>
<a href="#bitcoin-core-24539" class="anchor-list-link">●</a>
Bitcoin Core #24539
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('51:57')" class="seek">51:57</a><noscript>51:57</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-24539">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-24539-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-core-34329" class="anchor-list">
<p>
<a href="#bitcoin-core-34329" class="anchor-list-link">●</a>
Bitcoin Core #34329
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('53:52')" class="seek">53:52</a><noscript>53:52</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-34329">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-34329-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-core-28792" class="anchor-list">
<p>
<a href="#bitcoin-core-28792" class="anchor-list-link">●</a>
Bitcoin Core #28792
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('15:35')" class="seek">15:35</a><noscript>15:35</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-28792">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-28792-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-core-32138" class="anchor-list">
<p>
<a href="#bitcoin-core-32138" class="anchor-list-link">●</a>
Bitcoin Core #32138
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('54:56')" class="seek">54:56</a><noscript>54:56</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-32138">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-32138-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-core-34512" class="anchor-list">
<p>
<a href="#bitcoin-core-34512" class="anchor-list-link">●</a>
Bitcoin Core #34512
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('56:44')" class="seek">56:44</a><noscript>56:44</noscript>)
<a href="/en/newsletters/2026/02/27/#bitcoin-core-34512">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-34512-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="core-lightning-8490" class="anchor-list">
<p>
<a href="#core-lightning-8490" class="anchor-list-link">●</a>
Core Lightning #8490
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('58:16')" class="seek">58:16</a><noscript>58:16</noscript>)
<a href="/en/newsletters/2026/02/27/#core-lightning-8490">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#core-lightning-8490-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="eclair-3250" class="anchor-list">
<p>
<a href="#eclair-3250" class="anchor-list-link">●</a>
Eclair #3250
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('59:07')" class="seek">59:07</a><noscript>59:07</noscript>)
<a href="/en/newsletters/2026/02/27/#eclair-3250">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#eclair-3250-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4373" class="anchor-list">
<p>
<a href="#ldk-4373" class="anchor-list-link">●</a>
LDK #4373
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('59:55')" class="seek">59:55</a><noscript>59:55</noscript>)
<a href="/en/newsletters/2026/02/27/#ldk-4373">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4373-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bdk-2081" class="anchor-list">
<p>
<a href="#bdk-2081" class="anchor-list-link">●</a>
BDK #2081
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:02:13')" class="seek">1:02:13</a><noscript>1:02:13</noscript>)
<a href="/en/newsletters/2026/02/27/#bdk-2081">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bdk-2081-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
</div>
<h2 id="transcription">Transcription</h2>
<p><strong>Mike Schmidt</strong>: Welcome everyone to Bitcoin Optech Newsletter #394 Recap.
Today, we’re going to be talking about a draft BIP for output script descriptor
annotations, and we also have our monthly segment covering questions and answers
from the Bitcoin Stack Exchange. This week, Murch and I are joined by two
guests. First, Craig.</p>
<p><strong>Craig Raw</strong>: Hey guys.</p>
<p><strong>Mike Schmidt</strong>: Craig, folks are probably familiar with you, you were on
recently. But do you want to give a quick explanation of the kind of work you
do in Bitcoin?</p>
<p><strong>Craig Raw</strong>: Yeah, sure. So, I am responsible for building Sparrow Wallet,
which is quite well-known in the Bitcoin world. And I’ve recently been doing
some silent payments work, particularly around the BIPs. So, yeah, that’s kind
of what I’m busy with these days.</p>
<p><strong>Mike Schmidt</strong>: We’re also joined by Fabian. Fabian, what do you do?</p>
<p><strong>Fabian Jahr</strong>: Yes, I’m a Bitcoin Core open-source developer, so mostly
focused on Bitcoin Core and supported by Brink, but I also spend my time a bit
to some more research topics around new BIPs and also exploring secp256k1 as
well now.</p>
<p><strong>Mike Schmidt</strong>: Excellent. Thank you both for joining us. For those
following at home, we’re going to start with the news section with Craig, and
then we’ll move to Fabian’s item, which is actually from the Notable code
segment.</p>
<p id="draft-bip-for-output-script-descriptor-annotations-transcript"><em>Draft BIP for output script descriptor annotations</em></p>
<p>“Draft BIP for output script descriptor annotations”. Craig, you posted to the
Bitcoin-Dev mailing list about a draft BIP for output script descriptor
annotations. It sounded like this came out of your work on your other proposal
for silent payment output script descriptors, which has BIP392, I believe. We
had you on to talk about that in Optech Recap #387, and you had mentioned during
that discussion that there was some consternation that some folks had about
including certain types of data in the descriptors. Maybe you can recap that
discussion a bit, and then we can get into what you’ve come up with as a
potential solution.</p>
<p><strong>Craig Raw</strong>: Yeah, sure. So, in the development of the output descriptive
format for silent payments wallets, we came across these two kind of conflicting
needs. One is that silent payment wallets, because they are computationally
very heavy when it comes to scanning, they really need the advantage of knowing
where to start, so what block height to start on. Without that, it can really
become impossible, for example, for a mobile wallet to ever actually recover a
wallet, because it has to start from the very beginning, which is generally
considered to be taproot activation. So, that’s the one need. The other need
is that output descriptors generally never have something like a block height in
them, because it’s considered to be extraneous information, sort of metadata
which is not absolutely required to create the output scripts. So, we have
these two kind of conflicting reasons, one to add them, one not to. And in the
end, the BIP for output descriptor annotations is what emerged. So, it came out
of a discussion that I was having, as you referred to, Mike, which is really
just talking about how to manage this tension between what we put into a
descriptor and what we leave out.</p>
<p><strong>Mike Schmidt</strong>: Awesome. So, the idea is for this additional metadata, I
think you had a creative way of using a URL-like delimiter to sort of append
those key values to the script, right? And then, the follow-up would be,
included in this proposal is also the first usage of that, which would be for
the birthday, right?</p>
<p><strong>Craig Raw</strong>: That’s right. So, there’s basically this annotations format.
So, what an annotation really is, is just some extra information about whatever
the thing is, so that’s all that we’re trying to do here. We’re trying to
provide some additional information, which can assist in the reading or the
parsing of this particular piece of information, the information being the
output script descriptor. Now, the additional information that we can provide
here that is of use, we currently have three different keys that we can add.
According to the BIP, we can add the block height, which I mentioned, very
important for silent payments wallets, but also quite important for normal HD
wallets, because often, for example, in Bitcoin Core, in that wallet, you need
to start from a particular block height, or at least you would want to because
it makes the scanning process take much less time. So, that’s actually quite
useful across all wallets. And then, we have this idea of the gap limit, which
is an HD wallet-only thing. So, we have an idea of how far ahead in the chain
are we going to look for addresses that have funds in them. We have to stop
after a certain point; what is that point at which we stop?</p>
<p>So, wallets have defaults but often you end up in a situation where, for
example, you might have a customer who’s requested many addresses without paying
to them, and then you have a gap limit which extends out beyond that default.
And this allows us to specify a higher number than that default and put it right
there into the output descriptor so we can recover that wallet. And I’m sure
that there’d be people out there who’ve had to increase the size of that gap
limit variable before in order to properly recover all the funds in their
wallet. So, that’s the second key. And then, the third one is a silent
payments wallet one, which most people will not be aware of. There’s this thing
called labels. It’s a bit of a contentious thing because labels do increase the
scanning burden, every label that you add increases the burden that you place
onto the client wallet that’s trying to recover the funds. But at any rate, we
need some kind of a way to be able to say, “There might be funds at these
additional labels”. And this just basically sets an upper bound for that in the
same way that the gap limit sets an upper bound.</p>
<p>So, those are the three different keys that you can specify. And you do that
very simply with what looks like the kind of key value pairs that you put onto a
URL. So, it’s a question mark at the end of an output descriptor, and then
key=value. And they’re quite short, because we want to keep them short for QR
codes. So, it’s just BH for block height, and gap limit GL, and then max label
ML. So, those are the three different keys. And that’s really it, they’re just
integers in the values of those. That’s the entire BIP.</p>
<p><strong>Mark Erhardt</strong>: Maybe just very briefly, the label count is also just set by
the user of the wallet. So, I believe you publish a different public scan key
if you have a different label, right? So, it wouldn’t be that someone else
decides to send to a higher label, but the wallet owner would publish another
label.</p>
<p><strong>Craig Raw</strong>: Yes, that is correct. But of course, if you wanted to recover
that wallet on some other wallet software, you would need to have some record
somewhere of how many of these labels you had created in the past.</p>
<p><strong>Mark Erhardt</strong>: Yeah, and then maybe let me just try to jump in and explain
why this is a separate proposal. So, I think the contention in that discussion
was the output script descriptors describe how output scripts are constructed,
the pattern of output scripts that the wallet receives funds to. And obviously,
the information on when a wallet was started to be used or how big the gap limit
would be or how many labels there are, are not really related to the output
script pattern. So, this is a separate piece of information that pertains more
to the meta information about the wallet. And that, I think, was why there was
pushback on including that in the output script descriptor directly. So, it’s
this second annotation on top of the output script descriptor instead.</p>
<p><strong>Craig Raw</strong>: Yes, I think that that’s a very accurate way of saying it. Yeah.
I think it’s, you know, we’re just speaking very practically. I’ve experienced
a lot of people in the past who’ve had issues trying to recover wallets just due
to practical things like, “I haven’t seen all my funds yet”. And the general
advice, in fact one of the very common things that you will get if you say that
is, “What is your gap limit? You need to increase that”. And then, that is
usually the answer. So, just having a way that people don’t have to think about
it, don’t have to go through that support process, it’s just there; and so, I
think going to be quite useful.</p>
<p><strong>Mark Erhardt</strong>: Yeah, I think all of these are very useful and important to
have. I think maybe it would also be time to generally just work with bigger
gap limits by default. But then, of course, that introduces the problem that if
someone were to actually go even beyond that, you’d have to increase it again to
scan. But yeah, so being a BIP editor, I saw your draft already and it had a
very good early showing. Have you heard any more feedback on it? Someone told
me it’s going to get a number soon, I think. And is there any other open
questions or thoughts that you’ve been noodling on that one?</p>
<p><strong>Craig Raw</strong>: No, actually, I think it’s one of those ones which has just kind
of come together as a natural flow. I’m probably going to jinx it just by
saying this, but it seems to be the least contentious proposal that I’ve put
forward. So, yeah, I think anybody who’s been in Bitcoin for any length of time
knows that this is a pain point and is happy to see some kind of an answer. I
think all of the silent payment wallet devs particularly know that this is going
to be a pain point and need some kind of an answer. So, that’s where I think
it’s at. But yeah, not a lot of feedback at this point. I think people have
seen it, it obviously was in the Optech Newsletter last week, and we’ll see if
there’s any feedback based on this interview now.</p>
<p><strong>Mark Erhardt</strong>: Yeah, and maybe just to double-down on what knowing the birth
date of a wallet would mean, because I think that one is the most interesting
out of the three to dive into a little bit. So, for a silent payments wallet,
you have to basically scan every single P2TR output that still exists in order
to recover all your funds. And to get your full wallet history, you actually
have to scan all the P2TR outputs that were created since your wallet was
created. So, by knowing the block height at which your wallet was created, or
at which it received funds for the first time, allows you to just only scan from
there, only scan the subset of P2TR outputs that were created since then, and
only search for the wallet history from that height, which could, given that
taproot’s been out for, what, four years now, would significantly cut down the
number of P2TR outputs you have to scan. And if you have a light wallet or a
mobile phone wallet that is doing the scanning, this will mean that you get
access to your funds way, way quicker.</p>
<p><strong>Craig Raw</strong>: Yeah. And I think if you just project out another four or five
years and expect those poor mobile phones to have to scan through all of that
with increasing taproot usage as well, I really think we’re going to have to
avoid scanning from the start; we’re going to have to scan from a later date.
So, yeah, that I think explains it well.</p>
<p><strong>Mike Schmidt</strong>: Craig, talk to me about this key value URL-like appending.
Is that just a simply an elegant way, since those characters were already
defined and supported, for you to get this data in with the existing descriptor,
or is there more going on there?</p>
<p><strong>Craig Raw</strong>: Yeah, it’s actually a good point. So, in doing this output
script descriptor work, both of these BIPs, I’ve had cause to go back to the
original BIP380, which is the first sort of defining BIP for how these things
work. And if you read the motivation for that BIP, it’s actually around
backups, it’s actually around how do people backup their wallets. So, this is
clearly intended to be a format that is used by people, by actual users. It’s
not just a dev kind of thing. And as a result, I think having a format that is
human-readable and not too techie, and it’s not like a binary thing, it’s not
JSON, I think that that’s kind of the really intelligent part of it, and I think
you want to stay within that. So, a lot of people, when they think of how to
solve this, they needed to think of all these other formats. But actually, you
kind of look at it and you think, well, a URL and the parameters of a URL are
one of the most well-understood things. Sure, not everyone understands them,
but most people can look at them and take a guess at what it is. So, it kind of
makes it a really human-friendly thing, and I think that that’s very important
for what is effectively a backup format.</p>
<p>That kind of thinking has guided all of my work in terms of this development.
It’s just everyone kind of knows at the end of a URL, you’ve got this question
mark, and then you’ve got these key value pairs, which are separated by
ampersands. And that’s effectively all that that does, is it just reuses that.
And they all happily are part of the legal characters allowed by BIP380, so it
kind of already fitted in there. And of course, we have the ability to add
further key values to this at a later date. These are not the defined end point
of this, but we can obviously evolve this over time as new wallet types might
evolve in the future.</p>
<p><strong>Mike Schmidt</strong>: Excellent. That was all the questions from me. Murch or
Fabian, anything else? Craig, do you want to give a call to action to any
listeners, other than read the draft BIP?</p>
<p><strong>Craig Raw</strong>: Yeah, I mean nothing other than I think what people have heard.
If you have any other thoughts, send them through. But I do think it is a
pretty straightforward BIP. So, yeah, hopefully we can start using it soon.</p>
<p><strong>Mike Schmidt</strong>: Awesome. Thanks for your work on this, Craig. Thanks for
joining us.</p>
<p><strong>Mark Erhardt</strong>: Yeah, thank you.</p>
<p><strong>Craig Raw</strong>: Sure.</p>
<p id="bitcoin-core-28792-transcript"><em>Bitcoin Core #28792</em></p>
<p><strong>Mike Schmidt</strong>: Cheers. We’re going to jump to the Notable code and
documentation section of the newsletter here, because we have Fabian to talk
about Bitcoin Core #28792, which bundles embedded ASMap data directly into the
Bitcoin Core binary. We want to talk with Fabian about, what data are we
talking about? What is ASMap? Do you pronounce it ASMap or A-S-Map? Take us
from there, Fabian.</p>
<p><strong>Fabian Jahr</strong>: Nobody knows! It’s also which letters you write, in which way,
is even contentious. But I give up trying to streamline that. But what matters
is the functionality, so let’s focus on that. So, ASMap, the first part maybe
that’s not so clear to everyone, is the AS part. AS stands for Autonomous
System. And on the internet, to be precise, the clearnet that we are using
every day probably, it’s the name for the entity that controls IP addresses.
So, Autonomous Systems can control any number of IP addresses. Usually, they
are bundled in what’s called a prefix. And so, if you have an IP address in
front of you, in your head, the part that’s more to the left, it’s a larger part
basically, like in a normal number. And the part that is in the back, the
smaller numbers, they are often controlled by the same entity. But that doesn’t
have to be always the case. Autonomous Systems can control a large variety of
IPs that look very differently. And so, that’s what’s in the AS map itself. It
maps the Autonomous Systems, which also have numbers, to the Ips, and it tells
you, in a very compressed format, which Autonomous System controls which IPs.
And that’s very important for us, or it can be very important for us, to use it
for basically deciding which peers we make a connection to, to ensure that we
connect to peers that have a diverse way of accessing the internet, so they
cannot intercept it or be controlled, of course, in some kind of way.</p>
<p>Currently, Bitcoin Core already does something to try to get a diverse set, but
they just look at the IP because that’s all the information that there is right
now. And the functionality for ASMap was already added to Bitcoin Core earlier.
However, the information of the map, that was not readily available. So, you
needed to source this information from somewhere, upload it into Bitcoin Core,
and then this functionality was available. But of course, it’s something that
not a lot of people are doing. It’s often mentioned probably on a podcast as
well that defaults are often not changed. And so, yeah, that’s why there was a
need for adding this data into the binary directly.</p>
<p><strong>Mark Erhardt</strong>: All right. So, ASMap is basically a map of who controls what
parts of the internet. And one of the ways that that is relevant to us is to
protect us against eclipse attacks or Sibyl attacks. So, when there is someone
that spins up a ton of nodes, they are all with the same provider, the ASMap
will tell us that all of these IP addresses, even if they look different, they
are controlled by the same Autonomous System. And therefore, we should
categorize them as potentially, or more likely to be controlled by the same
entity, right? So, it sort of guides us to who we want to connect to, as in
peers, and diversify the peer connections that we have, to get them away from
being controlled all by the same entity, right?</p>
<p><strong>Fabian Jahr</strong>: Yes, that’s right.</p>
<p><strong>Mark Erhardt</strong>: So, far so good. So, I saw recently in the Bitcoin Core
meeting that a few people were talking about coordinating the ASMap readout. Do
you want to tell us a little bit how it works that we can trust this ASMap?</p>
<p><strong>Fabian Jahr</strong>: Yes, sure. So, first of all, why is this something that is so
complicated that I’m going to explain now? What we’re basically doing is a map
of the internet, and the map of the internet is constantly changing. There are
messages to the order of several hundreds to thousands in a second, or
definitely within a minute, that are flying around, that are changing who
controls which IPs. And so, what we’re really doing is just a snapshot. And we
want to just minimize the snapshot that we’re producing. And the way that we do
it is that we do it at the same time across different computers for different
people, so that we can see that several people got a match between the maps that
are coming out of this process. And so, we know, okay, we don’t just have to
trust one person that created it, but rather we can trust that the set of people
is trusting this. And kind of the bar that I set there roughly is similar to
any PR to Bitcoin Core, it’s being reviewed by several people and only when
several people give an ACK, then it’s merged.</p>
<p>So, I wrote a software that does this, where you basically can give a timestamp
and at the exact timestamp, it’s going to start this process. It’s pulling data
from different sources and merging them in a way that is reproducible and it’s
the same across all computers, independent of if the computer is slow or fast,
or whatever. And so, this still doesn’t solve all processes, all potential
problems, but there’s a high likelihood that the majority of the people that run
this process, usually it is even better, we had like 80%, 90% of people also get
the same result. And so, when you see, for example, ten people doing this
process and they are all Bitcoin Core developers that are usually trustless,
that they do a good job with writing the code that you run and reviewing the
code that you run, that eight or nine of them got the same result, then you
should be also able to trust that the data that is in the map is also something
that is not malicious.</p>
<p><strong>Mark Erhardt</strong>: Yeah, I saw the PR. There was a bunch of responses right
around the same time and people produced the same fingerprint. And then, there
were a couple that got different results. And finally, the one that the vast
majority of the responses agreed on got merged into Bitcoin Core. So, this is
shipping with v31, but it’s not on by default.</p>
<p><strong>Fabian Jahr</strong>: Exactly, yeah. So, the on by default, of course, is something
that would be great to do in the future, and that’s a goal for the future.
However, there are still some questions about implications for this. And also,
it’s something new, there’s some process outside of the code. It’s not just new
code that we’re adding, but there’s a whole process of doing this, what I just
described for each release, because these maps are also getting outdated. So,
we need to do this again and again for every release. It’s fine to raise some
questions, but it’s good already now that people just have basically to give an
argument and not to source some file from somewhere on the internet. So, this
is one step in this progression and then hopefully in the future, we are sure
enough that the process works and the data is fine and that it helps us with the
network, and then we will turn it on by default.</p>
<p><strong>Mark Erhardt</strong>: All right. So, currently I think people run with the -asmap
flag to start using the ASMap, but do you have any data on how quickly this map
outdates or becomes less useful? Does it deteriorate within months or is it
years or days?</p>
<p><strong>Fabian Jahr</strong>: Seconds even! So, like I said, every second there’s
announcements that change what the routing is and then that also affects the
map. So, technically the map is outdated at the moment when this run that I
described earlier finishes.</p>
<p><strong>Mark Erhardt</strong>: You’re not selling that right now, you’re not selling it!</p>
<p><strong>Fabian Jahr</strong>: Yes, I know. But the thing is that the data is still good
enough largely. So, there is some data that changes very frequently, even
there’s some stuff that just basically flip-flops all the time, and it’s kind of
known that it’s kind of meaningless that this happens. And then, over time,
this data outdates to, I think we saw roughly 1% or so per month if you lay it
out, and maybe like 10% per year or so. So, this is just estimates based on the
data that we’ve created historically from the maps. However, the underlying
belief of why we think it’s still great to add these maps to Bitcoin Core and
even to use this with a release that is maybe like three, four months old, is
that this knowledge still is way, way better even when it’s outdated for one or
two years than using just the IP, like the current default that we’re doing.
It’s just really not helping much at all, because just looking at the IP is just
not giving us much information in terms of preventing eclipse attacks, etc. So,
even some outdated maps will still be very helpful.</p>
<p><strong>Mark Erhardt</strong>: Right. So, the bigger Autonomous Systems are pretty stable,
the Amazons, the Hetzners, and so forth, and they will remain on their IP
addresses pretty stably. Smaller ones might switch a little more. But
generally, this just gives you a better understanding of what to map together
and it continues to be useful. Would you say that you’re going to do a new
ASMap snapshot for every point release then too?</p>
<p><strong>Fabian Jahr</strong>: Yeah, I mean usually with the point releases, I think they’re
now a bit more away from the major releases. It used to be that more came out,
I think, closer together, maybe it’s just my memory wrong, but I felt like
initially when I made this plan, that we would just put the same map that we put
in the major release into all of the point releases that are coming around at
the same time. But if they are drawn out, then we could also put a different
map into these. But yeah, I think doing a point release is a good opportunity
to update the map as well. And so, what we’re really doing is we are, at least
right now, producing on a monthly basis at least one new map. So, there’s
always one recent map that is less than four weeks old that you can take from at
any point in time. And if there’s a need for it, we can always do this process
more or less simultaneously, or we could increase the frequency of this if it’s
necessary. So, yeah, anytime there’s a point release needed and we want to
update it, that is potentially there. However, there was not a big discussion
that this is now a rule that we fixed already, but I think that’s what we should
do.</p>
<p><strong>Mike Schmidt</strong>: Fabian, you may be understating the engineering effort or the
challenge that was ahead of you with putting this together. Do I remember
correctly that you went to one of these internet networking conferences, or some
such thing, and talked to people about the feasibility of even aggregating this
data, and they said it was impossible; do I have that memory correct?</p>
<p><strong>Fabian Jahr</strong>: Yeah, roughly that’s the way it went. I mean, I took over this
kind of, I wouldn’t say responsibility, but the project had been going on for a
while. Like I said, the feature was implemented in Bitcoin Core, but then this
data-sourcing stuff and so on was not really being worked on. So, I kind of
started working on that in 2022. And I also had still a lot to learn of how
this worked and how the players kind of acted and where we could get this data
in the best trust-minimized way, basically. And so, there’s not a lot of good
documentation there. If you think Bitcoin Core documentation is not ideal, this
is way, way worse. It’s a lot of old school. This is not 15 years old, like
Bitcoin, but it’s like 30, 40 years old technology, and a lot of big
corporations that don’t really care about writing anything open-source or
putting it on the internet in the open, but rather they meet in suits in
conference rooms and that’s where the knowledge is exchanged. And so, yeah, for
me, it was really a big breakthrough that there was a conference that just
happened to be around the corner from where I lived, at a point where I had
already spent a couple of months looking into this, but really feeling unsure
about the insights that I had gotten so far.</p>
<p>So, I went to this, it’s called a RIPE conference. RIPE is basically the
European authority on the internet across the continent. And so, there I met a
couple of people and interviewed them about what they thought about it. And so,
I got some good feedback from some people that were more open-minded, I guess,
on this kind of project. But also, some people straightforward said, “No, this
is impossible”. And basically, what they meant is impossible is like what I
said, like this data changes every second. And so, getting a snapshot across
different computers or getting an authoritative snapshot in some kind of way is
basically impossible. But yeah, this still works out great for our purpose.
But that’s kind of the reason why we have this majority rule of most people that
run this process should get a match and not everyone can have a match all the
time.</p>
<p><strong>Mark Erhardt</strong>: So, are you going to go back and tell them what you’ve
achieved and show them that it was possible?</p>
<p><strong>Fabian Jahr</strong>: Yes, I would really like to do that. I haven’t really found
the time to look at this opportunity. I have to say, at this conference also
not everyone is a Bitcoin fan. So, I’m not sure how it would be received if I
asked to give a talk. But yeah, I want to try at least once in the future.</p>
<p><strong>Mike Schmidt</strong>: Are there other parties, projects, interested in this data
set? I don’t remember if, in our discussion here you’ve mentioned, but there’s
this cartograph tool. Are there other people interested in the tool or the
resulting map for their own uses? I guess it could be other crypto projects,
but I’m more curious about things even outside of that.</p>
<p><strong>Fabian Jahr</strong>: Yeah, I haven’t really done any marketing on it yet, but it’s
potentially interesting for any kind of distributed network that wants to have
protection and wants to have diversity in terms of peers. So, for example, what
Tor does is Tor has a mapping of IPs to countries. It’s called GeoIP. And so,
it’s basically the same thing, just there’s a country instead of the Autonomous
System number. And the background for them is they have a bit of a different
threat model than we have for Bitcoin. They are more afraid of state-level
surveillance on dissidents and big walls around countries. And so, that’s why
this data makes a bit more sense for them. But I think, for example, the ASMap
would also be helpful for them in addition to that. Somebody talking also that
they find this interesting, this approach that we’ve taken, and the map that
they are using is basically coming out of a proprietary system that gives it to
them for free, for a license that allows them to use it in their context. But
there’s no reproducibility, there’s no transparency how this data is really
constructed. So, I think this approach could be possible for them as well. And
so, yeah, maybe it’s interesting for them in the future.</p>
<p><strong>Mark Erhardt</strong>: So, how possible would it be to derive the country information
from the ASMap? Is that readily available, is that right there? It would need
to come from a different source. All of that information is also available.
So, there, I would need to add some additional research in terms of what the
best source is. But this is a bit easier to get even than the information that
we’re using now.</p>
<p><strong>Mark Erhardt</strong>: Well, it would be pretty cool if you could support Tor in that
way.</p>
<p><strong>Fabian Jahr</strong>: Yeah, I agree.</p>
<p><strong>Mike Schmidt</strong>: Very cool work, Fabian. Thanks for coming on and discussing
this particular PR, but the broader initiative I think is interesting for folks
as well. So, thanks for your time.</p>
<p><strong>Fabian Jahr</strong>: Yeah, anytime people want to contribute to this as well, it’s
not just in Bitcoin Core, but there’s also this ASMap GitHub organization where
we have the related repositories, the cartograph project, it’s in Python. So,
if you’re interested in that, feel free to come along, try it out and
contribute.</p>
<p><strong>Mike Schmidt</strong>: And do you have scheduled times that come out where people,
like listeners, could see if there’s like a notice that this is going to be the
next day where we all run it, whoever wants to participate in it runs it?
People may want to do that. What’s the timing of that kind of thing?</p>
<p><strong>Fabian Jahr</strong>: Yeah, so currently we do it on the first Thursday of the month
usually. Not sure what exactly the times, but always the same time, I think
4.00pm CET or so roughly. And yeah, but we opened, like there’s an issue on the
ASMap data repository that used to be in the ASMap org, but now it’s in the
Bitcoin Core org, because that’s where the data is stored, basically, that then
later goes into the Core releases. But there, you should see several days, if
not weeks in advance, when the next run is happening. And then, yeah, you can
take your time to configure a cartograph on your system and start it in advance.
And then, it’s going to run and do its thing and then you can post your result
afterwards.</p>
<p><strong>Mike Schmidt</strong>: Thanks again Fabian. Cheers.</p>
<p><strong>Fabian Jahr</strong>: Thank you.</p>
<p id="is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic-transcript"><em>Is Bitcoin BIP324 v2 P2P transport distinguishable from random traffic?</em></p>
<p><strong>Mike Schmidt</strong>: We have our monthly segment on Q &A from the Bitcoin Stack
Exchange. We picked out two this month. First one, “Is Bitcoin BIP324 v2 P2P
transport distinguishable from random traffic?” So, this is v2 encrypted
transport, BIP324, where communications between nodes are encrypted. And this
person’s asking whether it’s distinguishable from random traffic, or if there’s
things that BIP324 does to make it blend in with other types of traffic. And
then Pieter Wuille, who helped out with BIP324, answered that BIP324 does
support traffic-shaping features. And, Murch, correct me if I’m wrong, but is
that like the decoy packets, or is that something else?</p>
<p><strong>Mark Erhardt</strong>: Yeah, I believe that’s the case.</p>
<p><strong>Mike Schmidt</strong>: So, you can contrive your own ability to send basically
garbage data, but an observer wouldn’t know that that’s not garbage data. They
could think it’s streaming encrypted video, or whatever. You could throw off
observers with that. But that is not supported in BIP324 implementations today,
but the hooks are there for somebody who wants to be able to decoy their traffic
even more. Obviously, I think the data is random, but the amount of data that
you send and the timing of the data is not random, so these decoy packets would
allow you to confuse an observer. Do I have that right, Murch?</p>
<p><strong>Mark Erhardt</strong>: Yeah, that’s right. So, first, the handshake before you
actually start the encrypted connection would reveal that you always send a secp
point, you know, elliptic curve point. So, that would be distinguishable from
just pure random data. And then of course, for example, when blocks are found,
the blocks will propagate through the network. And if you’re an ISP and
watching node connections, you might see that, “Oh, this user always sends data
when a Bitcoin block was found. So, probably, even though it’s random, just by
correlating the timing, they’re probably a Bitcoin node”, right?</p>
<p>What is very interesting is because the encryption format is easy to mimic by
other parties, other parties could choose to hide their traffic as looking like
Bitcoin traffic. And so, for example, the Tor network or encrypted chat apps,
or other applications like that, could choose to make their traffic look like
Bitcoin traffic. And in that way, it is probably easier to get obfuscation out
of it than in the other way, because Bitcoin traffic will, by timing, always
look like Bitcoin traffic. The Bitcoin transactions that go through the network
when there’s big transactions, they will gossip through the network, when
there’s blocks they will gossip through the network. The initial handshake is
slightly recognizable. We could stuff more data in there, but the actual
underlying Bitcoin data that flows would flow whenever that Bitcoin data flows.</p>
<p>Now, the interesting thing is because we use the mempools and compact block
relay to reconstruct blocks, the spike in traffic at block discovery is not as
big as it used to be ten years ago or so before compact blocks. I’m familiar
with an anecdote of a well-known Bitcoin developer that was on a video chat with
a few colleagues and a Bitcoin block was found, and two of his colleagues’ video
streams started stuttering for a moment. And he’s like, “Aha, running a Bitcoin
node”. That wouldn’t happen as much anymore because the compact block
announcements are much smaller and most Bitcoin transactions should be available
in your mempool already, sent to you in the last hour or so before the block.
So, these spikes don’t happen as much anymore. But yeah, we can put more stuff
in there to make it look smoother or obfuscate that it’s Bitcoin traffic
eventually.</p>
<p id="what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block-transcript"><em>What if a miner just broadcasts the header and never gives the block?</em></p>
<p><strong>Mike Schmidt</strong>: Second question from the Stack Exchange, “What if a miner just
broadcasts the header and never gives the block?” Murch, I know you jumped into
this one. I don’t know if you prefer taking this or you want me to go through
it.</p>
<p><strong>Mark Erhardt</strong>: Yeah, I can talk a little bit about it. So, we announce
headers first, right? But headers don’t propagate by themselves. We only use
the block header announcement as a way of telling our peers, “Hey, we have a
block header and here is already the first 80 bytes of the block, which proves
that the PoW was done, which shows that it attaches to the previous block, and
so forth”. So, us using the block headers to announce that a new block was
found instead of the inventory message that was used before, it provides
strictly more information for just a little bit more bytes. But the block
headers aren’t forwarded without the block. So, there is no such thing as block
headers propagating around the network without the blocks propagating around the
network. When a block is found and a node tells its peers, “Here’s a new block
header”, that also indicates that the node is willing to give you the block.
And the receiving peers will immediately respond with, “Well, where’s the block?
Give me the block too”. And then, only after receiving the block and processing
the block, they will forward the block header as an announcement to their peers,
unless they are in the high-bandwidth mode of compact blocks. Even then, they
will first receive the entire block before forwarding it, but push out the whole
block without verifying it first, and only after their peers told them to do so.</p>
<p>So, this whole question is a little confused in that regard, because block
headers by themselves do not propagate. But there is, of course, a thing called
spy mining, which I’m not sure how widely spread the practice is anymore,
because there was a huge hiccup in 2015, where upon activation of a soft fork,
someone mined an invalid block and then switched to mining on top of their
invalid block. But all of their peers rejected the block as invalid because
they had actually upgraded to the soft fork already. So, the block was invalid
per the new rules enforced by the freshly-activated soft fork. And a bunch of
other miners started mining on top of that block template because they saw, “Oh,
miner XYZ switched over to a new block template. They must have found a block
that they will be propagating around the network”, but the block never came.
And they actually got, was it six? No, I’d have to look it up. I think in the
end, the chain got to some 30 blocks or so until – no, I’m mixing that up with
the March 2013 chain split. I think it was six blocks or so that were empty and
mined on top of an invalid block and they all lost their money on top of that,
because the chain was invalid because the first one was invalid.</p>
<p><strong>Mike Schmidt</strong>: Well, Murch, maybe get into what is spy mining, because I saw
that that was referenced here in Pieter Wuille’s response to the original
answer. And then, I thought it would be interesting to talk about it, and I saw
that we hadn’t really talked about it on Optech before. So, what are the rough
mechanics of spy mining?</p>
<p><strong>Mark Erhardt</strong>: Right, so spy mining is basically, you register as a miner on
other mining pools with your competitors. And when your competitors give out
new work packages referencing a previous block header, you also switch over your
own node to mine on top of the same block header. The big problem with that is
you only see the hash of the previous block. So, you don’t actually see the
block header. If you saw the block header, the block header would actually show
that the proof of work had been done, because block ID is the hash of the block
header, and that has to be lower than the difficulty target, right? So, when
you see the block header, you actually see that a ton of work had been done, and
that would make you way more confident that the block header is probably valid,
because otherwise people wouldn’t have spent that amount of work. But when you
just receive the work package, you only see the hash. And the hash could be
made up, because only with the block header, you get the confidence that the
work was actually done. Otherwise, you could just create a random string.</p>
<p>So, spy mining is this practice of reading the work packages of competing
miners; and when they give out new work packages, to guess that they probably
found a new block and the prior block hash is valid and you can mine on top of
that an empty block as well. And people used to do that at least, I don’t know
if they still do, but this is presumably where part of the empty blocks used to
come from. And the other one being, you have received a block header and before
finishing to validate the block, you give out new work packages with an empty
block on top of the block header. So, yeah, spy mining is basically trying to
shave off a few seconds or milliseconds by reading out the work package from
competing miners. And it’s kind of dangerous because if miners were adversarial
and wanted to make you waste mining power, hashrate, they might just issue a
work package to some of their miners that is fake, and then get the whole
competition all to switch over to their new block header, and then actually
secretly would continue mining on their old block because no new block was
found. So, spy mining has its risks.</p>
<p><strong>Mike Schmidt</strong>: Yeah, that makes sense. And even in the case that you would
see the PoW, you mentioned the, what was it, BIP66 reorg, where in my
understanding, the PoW was there, but it was invalid due to some of the
violations of the protocol rules that had recently changed, because they were
running outdated software. So, even if you had that, there could still be a
violation.</p>
<p><strong>Mark Erhardt</strong>: In that specific case, actually, the block header itself was
invalid, because BIP66 required to increment the block version and the invalid
block had a lower block version than permitted. So, in that case, if the block
header had been seen, the miners should have rejected the block. So, we know
for sure that they must have been spy mining and only saw the hash rather than
the header.</p>
<p><strong>Mike Schmidt</strong>: Releases and release candidates. Gustavo came down ill this
morning, so Murch and I are going to do the Releases and the Notable code, based
on his write-ups for this past week.</p>
<p id="bitcoin-core-28-4rc1-transcript"><em>Bitcoin Core 28.4rc1</em></p>
<p>First release, Bitcoin Core 28.4rc1, which is a maintenance RC and it contains
wallet migration fixes as well as the removal of an unreliable DNS seed, that
maybe you’ve heard about discussions.</p>
<p id="rust-bitcoin-0-33-0-beta-transcript"><em>Rust Bitcoin 0.33.0-beta</em></p>
<p>Second release, Rust Bitcoin 0.33.0-beta. This is a beta release for Rust
Bitcoin. We noted that it was a fairly large update in terms of number of
commits. We also noted a few different things that might be interesting for
listeners. There’s a new crate for bitcoin-consensus-encoding. They obviously
bumped the version across some of their sub-crates. We’ve talked about some of
the PRs here, including the MAX_MONEY, ensuring that transactions with duplicate
inputs or outputs, sums don’t exceed MAX_MONEY. I think we covered that
recently. And then, there’s P2P network message encoding traits have been added
as well. You can look back at some of the recent Rust Bitcoin PRs that we’ve
covered or you can dig into the release notes here.</p>
<p id="bitcoin-core-34568-transcript"><em>Bitcoin Core #34568</em></p>
<p>Notable code and documentation changes. We have a slew of Bitcoin Core PRs this
week that Murch is going to walk us through starting with Bitcoin Core 34.5.68.</p>
<p><strong>Mark Erhardt</strong>: Yes. So, as some of you might have noticed, we had
feature-freeze last Friday and we are getting ready to release Bitcoin Core v31
early April. So, people are getting their projects in and now, well, we’re
getting in their projects and now we’re down to just bug fixes and wrapping up
the rest of the things that go into the 31 version. Then, we will have the
branch off in, I think, a week or two and you’ll get v31 next month, hopefully,
as things go. So, Bitcoin Core #34568 makes several breaking changes to the
Mining IPC interface. So, if you work on Stratum v2 or have been using the
experimental Stratum v2 support so far, this one might be interesting to you.
It deprecates the methods getCoinbaseRawTx(), getCoinbaseCommitment(), and
getWitnessCommitmentIndex(). We’ve talked about these six newsletters ago in
Newsletter #388. And there are some new context parameters. The underlying
reason is that this will enable the event loop to not block on these calls and
hopefully makes it even better for Stratum v2. So, if you don’t do anything
with Stratum v2 or the Mining interface, you don’t have to look at this one.
But if you do, you should probably look at it.</p>
<p id="bitcoin-core-34184-transcript"><em>Bitcoin Core #34184</em></p>
<p>The next one up is Bitcoin Core #34184. This is also about the Mining IPC
interface. There’s an optional cooldown to the createNewBlock() method. And
the idea here is if you’re not completely caught up to the chain tip, you would
be producing outdated block templates while you’re catching up. So, the create
new block method now will wait, if you enable the option, until you’re caught up
to the chain tip, because otherwise it would just produce block templates that
are building on top of old blocks, and nobody needs that. So, this will prevent
Stratum v2 clients from getting all these templates that are outdated already at
creation. And there is also an interrupt method that you can call if you get a
new block while a block template is being created, that you immediately switch
over to the new chain tip. Again, if you’re interested in Mining IPC or in
Stratum v2, there are a bunch of interesting ones in v31 coming out. All of
this is, I believe, still going into v31.</p>
<p id="bitcoin-core-24539-transcript"><em>Bitcoin Core #24539</em></p>
<p>We continue with the Bitcoin Core #24539. This looks frigging ancient. 24000
is like probably seven years old or something. This adds a new -txospenderindex
option. And I think we talked about this last week already, right? Or maybe I
read the newsletter.</p>
<p><strong>Mike Schmidt</strong>: I think it might be the latter.</p>
<p><strong>Mark Erhardt</strong>: Okay. So, anyway, there’s a new index in Bitcoin Core that
keeps track of which transactions spent outputs. And that information was
previously not easily available. You had to basically search the blockchain to
find the transaction that spent an output. And with this index, you can get the
lookup in that direction, right? So, from a transaction, you can always look up
what transaction created an output, because that’s in the input. We have the
outpoint of the UTXO we’re spending in a transaction, that defines what UTXO
we’re spending, contains the txid, so we know what transaction created it. But
the other way is hard. When a transaction output was created, you have no clue
which transaction later spent it. So, this index, when you turn it on, you keep
track of that information and it is not required to have the -txindex on at the
same time, and it doesn’t work with pruning. So, if you’re interested in doing
blockchain explorers and things like that, this will be super-exciting for you,
I think. Yeah, sorry, I just learned this morning that I’m responsible for
these, so bear with me, please.</p>
<p id="bitcoin-core-34329-transcript"><em>Bitcoin Core #34329</em></p>
<p>Bitcoin Core #34329 adds two new RPCs, and these are in context of the new
private transaction broadcast. We talked about this one-shot broadcast method
through Tor when you turn on private broadcast. These two new RPCs allow you to
get information on what is currently in the queue for private broadcast, and to
abort attempts of private broadcast. So, these RPCs are called
getprivatebroadcastinfo and abortprivatebroadcast, and they allow you to get
information and manipulate or abort the attempts of privately broadcasting
transactions that are currently in the queue and being sent out via Tor to
single nodes, handshake, send a transaction, ping pong, and drop the connection.</p>
<p id="bitcoin-core-32138-transcript"><em>Bitcoin Core #32138</em></p>
<p>ll right, we already talked about ASMap quite a little bit, so I’m skipping that
one again. And we’re getting to Bitcoin Core #32138. This one removes an RPC
and a startup option. And confusingly, they are called settxfee and -paytxfee.
But of course, under the hood, they refer to feerates. So, with settxfee, you
were setting a standard feerate that you would use for every single transaction
when you send a transaction. And we live in times where feerates are actually
dynamic. So, making your node always use the same feerate is kind of a weird
thing, and it felt like a footgun to have a static feerate for all of your
transactions. So, this is being removed. The proper way or intended way how to
do this is when you send a transaction, you parse the current feerate that you
want to use. And if you always want to use the same feerate, you can use the
same feerate in your function call. But configuring a node to always use the
same feerate, come tide and high water, is just not really reasonable today
anymore.</p>
<p>The -paytxfee startup option is the same thing for the configuration. So, you
were able to configure your node to do this, instead of calling it via the
settxfee RPC. So, both of these were removed at the same time. And they were
deprecated already in v30. We talked about this in Newsletter #349. But the
general idea is either use automatic fee estimation or set a feerate right when
you call it.</p>
<p id="bitcoin-core-34512-transcript"><em>Bitcoin Core #34512</em></p>
<p>All right, one more. Lots of Bitcoin Core stuff. Bitcoin Core #34512 adds a
coinbase_tx field to the getblock RPC response. So, here, when you get a block,
there are different verbosity levels that you can request. And previously, if
you wanted to get information on what exactly the coinbase transaction looked
like, you had to go to verbosity 2, which meant that you would get every single
transaction in the entire block deserialized and presented in your RPC output.
Now, you might actually only want to look at the coinbase transaction. For
example, we’re currently excited that some people are starting to be compliant
with the BIP54 consensus cleanup requirements, which is to set the locktime in
the coinbase transaction to block height minus one. And I believe in the
context of this project, someone added that with verbosity level 1 and above,
you get the whole coinbase, but not all of the other transactions. So, if you
are looking at coinbase properties, coinbase transaction properties, not the
company – they stole the name from us, okay – anyway, if you are looking at
coinbase transactions, this RPC will be useful to get coinbase transaction
information without everything else. Back to you, Mike.</p>
<p id="core-lightning-8490-transcript"><em>Core Lightning #8490</em></p>
<p><strong>Mike Schmidt</strong>: All right, moving on with Core Lightning #8490, which adds a
payment-fronting-node configuration option. And this lets Core Lightning (CLN)
operators specify a node ID or multiple node IDs to use as an entry point for
incoming Lightning payments. So, this applies to BOLT11 invoices as well as
BOLT12 offers. Currently, the node that you provide that node ID must be one
that your CLN node has a channel with. That may change in the future, but
that’s how it’s set up now. And for BOLT11 invoices, CLN will use a route hint,
which provides a little bit of privacy. And for BOLT12 invoices and also
offers, CLN will provide a blinded path, which provides a bit better privacy.</p>
<p id="eclair-3250-transcript"><em>Eclair #3250</em></p>
<p>Eclair #3250 updates the OpenChannelInterceptor so that it can automatically
select a default channel_type, channel type being something like anchor channels
or simple taproot channels. Previously, such channel creations would fail
without an explicit type. In fact, you had to just provide the type or there
would be an error. But now Eclair will attempt to select the channel type,
using both the local node as well as the remote node features supported. So, it
takes both of those into account. Right now, I believe anchor outputs are the
default and the only option, but in the future, with taproot channels and zero
feed commitments, Eclair will have this preferred list of channel types that
they think are best and that can be overridden by the node operator.</p>
<p id="ldk-4373-transcript"><em>LDK #4373</em></p>
<p>LDK #4373 enables multiple wallets or nodes to collaboratively pay a single
invoice by each contributing a part of the payment. So, LDK behind the scenes
is using multipath payments to achieve this, and it adds this
total_mpp_amount_msat field, which allows providing this MPP (multipart payment)
amount that could be the total, which is larger than the local node is actually
sending. And then, the local node would contribute only a part of the payment
to, let’s say, a BOLT12 invoice. And then, the other payers can coordinate and
the receiver would then collect all these HTLCs (Hash Time Locked Contracts)
from all the contributing nodes and claim the payment once the full amount
arrives. I thought that the motivation for this PR was interesting and worth
quoting. So, this is from the PR description, “In some uses of LDK, we need the
ability to send HTLCs for only a portion of some larger MPP payment. This
allows payers to make single payments which spend funds from multiple wallets,
which may be important for ecash wallets holding funds in multiple mints, or
graduated wallets which hold funds across a trusted wallet and a self-custodial
wallet”.</p>
<p><strong>Mark Erhardt</strong>: I think the interesting thing here is, if you didn’t catch it,
previously we had MPPs that would originate from one node but go via multiple
routes. So, one node would send multiple packages via different routes and once
they reached the recipient, the recipient would collect multiple of them
together to get the full payment amount. This one has multiple nodes sending
partial payments, and so that’s new. And yeah, as Mike said, maybe multiple
mints. Maybe those phantom nodes that we’ve been talking about, where you
actually have multiple receiver nodes in front of a phantom node, and if you
don’t have enough funds, well, that would be shocking, but you could put stuff
together like this.</p>
<p id="bdk-2081-transcript"><em>BDK #2081</em></p>
<p><strong>Mike Schmidt</strong>: Last PR, BDK #2081, adds a created_txouts() and spent_txouts()
method to two different indexes in BDK, SpkTxOutIndex and KeychainTxOutIndex,
which are, I guess, an SPK, scriptPubKey, index, and I’m not sure what the
keychain index is. But these indexes have those methods to let wallets see
which tracked outputs a transaction spent and which ones it created.</p>
<p><strong>Mark Erhardt</strong>: I’m not sure if SPK stands for scriptPubKey here.</p>
<p><strong>Mike Schmidt</strong>: Maybe, we’ll see.</p>
<p><strong>Mark Erhardt</strong>: Maybe it’s secret public keychain or something. Anyway, I
don’t know.</p>
<p><strong>Mike Schmidt</strong>: We need an AI to tell us. I did try to poke around BDK to
see.</p>
<p><strong>Mark Erhardt</strong>: Oh, sorry, I was thinking Lightning still, so I think I’m
completely lost in the woods here. Probably a scriptPubKey, yeah. It’s BDK,
not LDK.</p>
<p><strong>Mike Schmidt</strong>: All right, I’ll take that as a win.</p>
<p><strong>Mark Erhardt</strong>: Just talking before my point arrived. Never mind.</p>
<p><strong>Mike Schmidt</strong>: We want to thank Craig and Fabian for joining us to talk about
what they’ve been working on earlier. We wish Gustavo well with his illness.
Hopefully, he’s back next week. And thank you, Murch, for co-hosting and doing
the Bitcoin Core PRs, and thank you all for listening. Cheers.</p>
<p><strong>Mark Erhardt</strong>: Hear you soon.</p>Bitcoin OptechMark “Murch” Erhardt and Mike Schmidt are joined by Craig Raw and Fabian Jahr to discuss Newsletter #394.Bitcoin Optech Newsletter #3942026-02-27T00:00:00+00:002026-02-27T00:00:00+00:00https://bitcoinops.org/en/newsletters/2026/02/2026-02-27-newsletter<p>This week’s newsletter looks at a proposed BIP for including supplemental
information with output script descriptors. Also included are our regular
sections summarizing popular questions on the Bitcoin Stack Exchange, announcing
new releases and release candidates, and describing recent changes to popular
Bitcoin infrastructure software.</p>
<h2 id="news">News</h2>
<ul>
<li id="draft-bip-for-output-script-descriptor-annotations" class="anchor-list">
<p><a href="#draft-bip-for-output-script-descriptor-annotations" class="anchor-list-link">●</a> <strong>Draft BIP for output script descriptor annotations</strong>: Craig Raw
<a href="https://groups.google.com/g/bitcoindev/c/ozjr1lF3Rkc">posted</a> to the Bitcoin-Dev mailing list about a new BIP idea to
address feedback that emerged during the discussion around BIP392
(see <a href="/en/newsletters/2026/01/09/#draft-bip-for-silent-payment-descriptors">Newsletter #387</a>).
According to Raw, metadata, such as the wallet birthday expressed as a
block height, could make <a href="/en/topics/silent-payments/">silent payment</a> scanning more efficient.
However, metadata is not technically needed to determine output scripts,
thus it is deemed unsuitable for inclusion in a <a href="/en/topics/output-script-descriptors/">descriptor</a>.</p>
<p>Raw’s BIP proposes to provide useful metadata in the form of annotations, expressed
as key/value pairs, appended directly to the descriptor string using URL-like query
delimiters. An annotated descriptor would look like this:
<code class="language-plaintext highlighter-rouge">SCRIPT?key=value&key=value#CHECKSUM</code>.
Notably, characters <code class="language-plaintext highlighter-rouge">?</code>, <code class="language-plaintext highlighter-rouge">&</code>, and <code class="language-plaintext highlighter-rouge">=</code> are already defined in <a href="https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki">BIP380</a>, thus the
checksum algorithm would not need to be updated.</p>
<p>In the <a href="https://github.com/craigraw/bips/blob/descriptorannotations/bip-descriptorannotations.mediawiki">draft BIP</a>, Raw also defines three initial annotation keys specifically to make funds silent payment scanning more efficient:</p>
<ul>
<li>
<p>Block Height <code class="language-plaintext highlighter-rouge">bh</code>: The block height at which a wallet received the first funds;</p>
</li>
<li>
<p>Gap Limit <code class="language-plaintext highlighter-rouge">gl</code>: The number of unused addresses to derive before stopping;</p>
</li>
<li>
<p>Max Label <code class="language-plaintext highlighter-rouge">ml</code>: The maximum label index to scan for, for silent payments wallets.</p>
</li>
</ul>
<p>Finally, Raw noted that annotations should not be used in the general wallet backup process,
but only for making funds recovery more efficient without altering the scripts
produced by the descriptor. <a href="/en/podcast/2026/03/03/#draft-bip-for-output-script-descriptor-annotations"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="selected-qa-from-bitcoin-stack-exchange">Selected Q&A from Bitcoin Stack Exchange</h2>
<p><em><a href="https://bitcoin.stackexchange.com/">Bitcoin Stack Exchange</a> 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.</em></p>
<ul>
<li id="is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic" class="anchor-list">
<p><a href="#is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic" class="anchor-list-link">●</a> <a href="https://bitcoin.stackexchange.com/a/130500">Is Bitcoin BIP324 v2 P2P transport distinguishable from random traffic?</a>
Pieter Wuille points out that <a href="https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki">BIP324</a>’s <a href="/en/topics/v2-p2p-transport/">v2 encrypted transport</a> protocol supports shaping traffic patterns, although no known
software implements that feature, concluding “today’s implementations only
defeat protocol signatures that involve patterns in the sent bytes, not in
traffic”. <a href="/en/podcast/2026/03/03/#is-bitcoin-bip324-v2-p2p-transport-distinguishable-from-random-traffic"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block" class="anchor-list">
<p><a href="#what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block" class="anchor-list-link">●</a> <a href="https://bitcoin.stackexchange.com/a/130456">What if a miner just broadcasts the header and never gives the block?</a>
User bigjosh outlines how a miner might behave after receiving a block header
on the P2P network but before receiving the block’s contents: by mining an
empty block on top of it. Pieter Wuille clarifies that, in practice, many
miners actually see new block headers by monitoring the work other mining
pools give out to their miners, a technique known as spy mining. <a href="/en/podcast/2026/03/03/#what-if-a-miner-just-broadcasts-the-header-and-never-gives-the-block"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="releases-and-release-candidates">Releases and release candidates</h2>
<p><em>New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.</em></p>
<ul>
<li id="bitcoin-core-28-4rc1" class="anchor-list">
<p><a href="#bitcoin-core-28-4rc1" class="anchor-list-link">●</a> <a href="https://bitcoincore.org/bin/bitcoin-core-28.4/test.rc1/">Bitcoin Core 28.4rc1</a> is a release candidate for a maintenance
release of a previous major release series. It primarily contains
wallet migration fixes and removal of an unreliable DNS seed. <a href="/en/podcast/2026/03/03/#bitcoin-core-28-4rc1"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="rust-bitcoin-0-33-0-beta" class="anchor-list">
<p><a href="#rust-bitcoin-0-33-0-beta" class="anchor-list-link">●</a> <a href="https://github.com/rust-bitcoin/rust-bitcoin/releases/tag/bitcoin-0.33.0-beta">Rust Bitcoin 0.33.0-beta</a> is a beta release of this library for
working with Bitcoin data structures. This is a large update with over
300 commits that introduces a new <code class="language-plaintext highlighter-rouge">bitcoin-consensus-encoding</code> crate,
adds P2P network message encoding traits, rejects transactions with
duplicate inputs or output sums exceeding <code class="language-plaintext highlighter-rouge">MAX_MONEY</code> during
decoding, and bumps major versions across all sub-crates. <a href="/en/podcast/2026/03/03/#rust-bitcoin-0-33-0-beta"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes">Notable code and documentation changes</h2>
<p><em>Notable recent changes in <a href="https://github.com/bitcoin/bitcoin">Bitcoin Core</a>, <a href="https://github.com/ElementsProject/lightning">Core
Lightning</a>, <a href="https://github.com/ACINQ/eclair">Eclair</a>, <a href="https://github.com/lightningdevkit/rust-lightning">LDK</a>,
<a href="https://github.com/lightningnetwork/lnd/">LND</a>, <a href="https://github.com/bitcoin-core/secp256k1">libsecp256k1</a>, <a href="https://github.com/bitcoin-core/HWI">Hardware Wallet
Interface (HWI)</a>, <a href="https://github.com/rust-bitcoin/rust-bitcoin">Rust Bitcoin</a>, <a href="https://github.com/btcpayserver/btcpayserver/">BTCPay
Server</a>, <a href="https://github.com/bitcoindevkit/bdk">BDK</a>, <a href="https://github.com/bitcoin/bips/">Bitcoin Improvement
Proposals (BIPs)</a>, <a href="https://github.com/lightning/bolts">Lightning BOLTs</a>,
<a href="https://github.com/lightning/blips">Lightning BLIPs</a>, <a href="https://github.com/bitcoin-inquisition/bitcoin">Bitcoin Inquisition</a>, and <a href="https://github.com/bitcoin-inquisition/binana">BINANAs</a>.</em></p>
<ul>
<li id="bitcoin-core-34568" class="anchor-list">
<p><a href="#bitcoin-core-34568" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/34568">Bitcoin Core #34568</a> makes several breaking changes to the Mining
IPC interface (see <a href="/en/newsletters/2024/07/05/#bitcoin-core-30200">Newsletter #310</a>). Deprecated
methods <code class="language-plaintext highlighter-rouge">getCoinbaseRawTx()</code>, <code class="language-plaintext highlighter-rouge">getCoinbaseCommitment()</code> and
<code class="language-plaintext highlighter-rouge">getWitnessCommitmentIndex()</code> (see <a href="/en/newsletters/2026/01/16/#bitcoin-core-33819">Newsletter #388</a>)
are removed, <code class="language-plaintext highlighter-rouge">context</code> parameters are added to <code class="language-plaintext highlighter-rouge">createNewBlock</code> and
<code class="language-plaintext highlighter-rouge">checkBlock</code> so they can run on separate threads without blocking the
<a href="https://capnproto.org/">Cap’n Proto</a> event loop, and default option values are
declared in the schema. The <code class="language-plaintext highlighter-rouge">Init.makeMining</code> version number is bumped
so that older clients receive a clear error instead of silently
misinterpreting the new schema. The threading change is a prerequisite
for the cooldown feature covered next. <a href="/en/podcast/2026/03/03/#bitcoin-core-34568"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-34184" class="anchor-list">
<p><a href="#bitcoin-core-34184" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/34184">Bitcoin Core #34184</a> adds an optional cooldown to the
<code class="language-plaintext highlighter-rouge">createNewBlock()</code> method on the Mining IPC interface. When enabled,
the method always waits for Initial Block Download (IBD) to complete
and for the tip to catch up before returning a block template. This
prevents <a href="/en/topics/pooled-mining/">Stratum v2</a> clients from being flooded
with rapidly outdated templates during startup. A new <code class="language-plaintext highlighter-rouge">interrupt()</code>
method is also added so IPC clients can cleanly abort a blocking
<code class="language-plaintext highlighter-rouge">createNewBlock()</code> or <code class="language-plaintext highlighter-rouge">waitTipChanged()</code> call. <a href="/en/podcast/2026/03/03/#bitcoin-core-34184"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-24539" class="anchor-list">
<p><a href="#bitcoin-core-24539" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/24539">Bitcoin Core #24539</a> adds a new <code class="language-plaintext highlighter-rouge">-txospenderindex</code> option that
maintains an index of which transaction spent each confirmed output.
When enabled, the <code class="language-plaintext highlighter-rouge">gettxspendingprevout</code> RPC is extended to return
the <code class="language-plaintext highlighter-rouge">spendingtxid</code> and <code class="language-plaintext highlighter-rouge">blockhash</code> for confirmed transactions, in
addition to its existing mempool lookups. Two new optional arguments
are also added to the RPC: <code class="language-plaintext highlighter-rouge">mempool_only</code> restricts lookups to the
mempool even when the index is available, and <code class="language-plaintext highlighter-rouge">return_spending_tx</code>
returns the full spending transaction. The index does not require
<code class="language-plaintext highlighter-rouge">-txindex</code> and is incompatible with pruning. This is particularly
useful for Lightning and other second-layer protocols that need to
track chains of spending transactions. <a href="/en/podcast/2026/03/03/#bitcoin-core-24539"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-34329" class="anchor-list">
<p><a href="#bitcoin-core-34329" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/34329">Bitcoin Core #34329</a> adds two new RPCs for managing private
transaction broadcasts (see <a href="/en/newsletters/2026/01/16/#bitcoin-core-29415">Newsletter #388</a>):
<code class="language-plaintext highlighter-rouge">getprivatebroadcastinfo</code> returns information about transactions
currently in the private broadcast queue, including the chosen peer
addresses and when each broadcast was sent, and
<code class="language-plaintext highlighter-rouge">abortprivatebroadcast</code> cancels the broadcast of a specific
transaction and its pending connections. <a href="/en/podcast/2026/03/03/#bitcoin-core-34329"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-28792" class="anchor-list">
<p><a href="#bitcoin-core-28792" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/28792">Bitcoin Core #28792</a> completes the embedded ASMap series of PRs by bundling
ASMap data directly in the Bitcoin Core binary, so users who enable
<code class="language-plaintext highlighter-rouge">-asmap</code> no longer need to separately obtain a data file. Removing the
build option <code class="language-plaintext highlighter-rouge">WITH_EMBEDDED_ASMAP</code> allows excluding the data. ASMap
improves <a href="/en/topics/eclipse-attacks/">eclipse attack</a> resistance by
diversifying peer connections across Autonomous Systems (see
Newsletters <a href="/en/newsletters/2019/06/26/#differentiating-peers-based-on-asn-instead-of-address-prefix">#52</a> and <a href="/en/newsletters/2024/02/21/#improved-reproducible-asmap-creation-process">#290</a>). The
feature remains off by default; the user must still specify <code class="language-plaintext highlighter-rouge">-asmap</code>
to enable it. A new <a href="https://github.com/bitcoin/bitcoin/blob/master/doc/asmap-data.md">documentation file</a> outlines the
process for sourcing the data and including it in a Bitcoin Core release. <a href="/en/podcast/2026/03/03/#bitcoin-core-28792"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-32138" class="anchor-list">
<p><a href="#bitcoin-core-32138" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/32138">Bitcoin Core #32138</a> removes the <code class="language-plaintext highlighter-rouge">settxfee</code> RPC and <code class="language-plaintext highlighter-rouge">-paytxfee</code>
startup option, which allowed users to set a static fee rate for all
transactions. Both were deprecated in Bitcoin Core 30.0 (see
<a href="/en/newsletters/2025/04/04/#bitcoin-core-31278">Newsletter #349</a>). Users should instead rely on
<a href="/en/topics/fee-estimation/">fee estimation</a> or set a per-transaction fee
rate. <a href="/en/podcast/2026/03/03/#bitcoin-core-32138"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-core-34512" class="anchor-list">
<p><a href="#bitcoin-core-34512" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/34512">Bitcoin Core #34512</a> adds a <code class="language-plaintext highlighter-rouge">coinbase_tx</code> field to the <code class="language-plaintext highlighter-rouge">getblock</code>
RPC response at verbosity level 1 and above, containing the coinbase
transaction’s <code class="language-plaintext highlighter-rouge">version</code>, <code class="language-plaintext highlighter-rouge">locktime</code>, <code class="language-plaintext highlighter-rouge">sequence</code>, <code class="language-plaintext highlighter-rouge">coinbase</code> script,
and <code class="language-plaintext highlighter-rouge">witness</code> data. Outputs are intentionally excluded to keep the
response compact. Previously, accessing coinbase properties required
verbosity 2, which decodes every transaction in the block. This is
useful for monitoring <a href="https://github.com/bitcoin/bips/blob/master/bip-0054.md">BIP54</a> (<a href="/en/topics/consensus-cleanup-soft-fork/">consensus cleanup</a>) coinbase locktime requirements or identifying mining pools
from the coinbase script. <a href="/en/podcast/2026/03/03/#bitcoin-core-34512"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="core-lightning-8490" class="anchor-list">
<p><a href="#core-lightning-8490" class="anchor-list-link">●</a> <a href="https://github.com/ElementsProject/lightning/issues/8490">Core Lightning #8490</a> adds a new <code class="language-plaintext highlighter-rouge">payment-fronting-node</code>
configuration option that specifies one or more nodes to always use
as entry points for incoming payments. When set, route hints in
<a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md">BOLT11</a> invoices and <a href="/en/topics/rendez-vous-routing/">blinded path</a> introduction
points in <a href="/en/topics/offers/">BOLT12</a> offers, invoices, and invoice
requests are constructed to use only the specified fronting nodes.
Previously, CLN would automatically select from the node’s channel
peers, potentially exposing different peers across invoices. The
option can be set globally or overridden per offer. <a href="/en/podcast/2026/03/03/#core-lightning-8490"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="eclair-3250" class="anchor-list">
<p><a href="#eclair-3250" class="anchor-list-link">●</a> <a href="https://github.com/ACINQ/eclair/issues/3250">Eclair #3250</a> allows the <code class="language-plaintext highlighter-rouge">OpenChannelInterceptor</code> to automatically
select a <code class="language-plaintext highlighter-rouge">channel_type</code> when the local node opens a channel without
one explicitly set. Previously, automatic channel creation (e.g., by
an LSP opening channels to clients) would fail unless a type was
provided. The current default prefers <a href="/en/topics/anchor-outputs/">anchor channels</a>, with <a href="/en/topics/simple-taproot-channels/">simple taproot channels</a> expected to take priority in follow-up PRs. <a href="/en/podcast/2026/03/03/#eclair-3250"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4373" class="anchor-list">
<p><a href="#ldk-4373" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4373">LDK #4373</a> adds support for sending <a href="/en/topics/multipath-payments/">multipath payments</a> where the local node pays only a portion of the
total invoice amount. A new <code class="language-plaintext highlighter-rouge">total_mpp_amount_msat</code> field in
<code class="language-plaintext highlighter-rouge">RecipientOnionFields</code> allows declaring an MPP total larger than what
this node sends, enabling multiple wallets or nodes to collaboratively
pay a single invoice by each contributing part of the payment. The
receiver collects HTLCs from all contributing nodes and claims the
payment once the full amount arrives. <a href="/en/topics/offers/">BOLT12</a> support
is left for a follow-up. <a href="/en/podcast/2026/03/03/#ldk-4373"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bdk-2081" class="anchor-list">
<p><a href="#bdk-2081" class="anchor-list-link">●</a> <a href="https://github.com/bitcoindevkit/bdk/issues/2081">BDK #2081</a> adds <code class="language-plaintext highlighter-rouge">spent_txouts()</code> and <code class="language-plaintext highlighter-rouge">created_txouts()</code> methods to
<code class="language-plaintext highlighter-rouge">SpkTxOutIndex</code> and <code class="language-plaintext highlighter-rouge">KeychainTxOutIndex</code> that, given a transaction,
return which tracked outputs it spent and which new tracked outputs it
created. This enables wallets to easily determine the addresses and
amounts involved in transactions they care about. <a href="/en/podcast/2026/03/03/#bdk-2081"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>Bitcoin OptechThis week’s newsletter looks at a proposed BIP for including supplemental information with output script descriptors. Also included are our regular sections summarizing popular questions on the Bitcoin Stack Exchange, announcing new releases and release candidates, and describing recent changes to popular Bitcoin infrastructure software.Bitcoin Optech Newsletter #393 Recap Podcast2026-02-24T00:00:00+00:002026-02-24T00:00:00+00:00https://bitcoinops.org/en/podcast/2026/02/2026-02-24-recap<p>Mark “Murch” Erhardt, Gustavo Flores Echaiz, and Mike Schmidt are joined by
Misha Komarov, Erik De Smedt, and arbedout to discuss <a href="/en/newsletters/2026/02/20/">Newsletter
#393</a>.</p>
<div id="podcast-links">
<a href="https://anchor.fm/s/d9918154/podcast/rss" title="Subscribe using RSS"><img src="/img/podcast/rss.png" alt="RSS icon" /></a>
<a href="https://podcasts.apple.com/us/podcast/bitcoin-optech-podcast/id1674626983" title="Subscribe using Apple Podcasts"><img src="/img/podcast/apple_podcasts.png" alt="Apple Podcasts icon" /></a>
<a href="https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9kOTkxODE1NC9wb2RjYXN0L3Jzcw" title="Subscribe using Google Podcasts"><img src="/img/podcast/google_podcasts.png" alt="Google Podcasts icon" /></a>
<a href="https://music.amazon.com/podcasts/d7540633-146f-4733-b716-4b38bafa8020/bitcoin-optech-podcast" title="Subscribe using Amazon Music"><img src="/img/podcast/amazon.png" alt="Amazon Music icon" /></a>
<a href="https://open.spotify.com/show/5UnB50h4O1jKaq5AyfN9Qo" title="Subscribe using Spotify"><img src="/img/podcast/spotify.png" alt="Spotify icon" /></a>
<a href="https://pca.st/tb9hbxoa" title="Subscribe using Pocket Casts"><img src="/img/podcast/pocket_casts.png" alt="Pocket Casts icon" /></a>
<a href="https://castbox.fm/channel/id5330863" title="Subscribe using Castbox"><img src="/img/podcast/castbox.png" alt="Castbox icon" /></a>
<a href="https://podcastindex.org/podcast/6071192" title="Listen on Podcast 2.0 players"><img src="/img/podcast/podcast-index.png" alt="Podcast Index icon" /></a>
<a href="https://anchor.fm/bitcoin-optech/" title="Listen on Anchor.fm"><img src="/img/podcast/anchor.png" alt="Anchor.fm icon" /></a>
</div>
<p><em>The Bitcoin Optech Podcast and transcription content is licensed Creative Commons <a href="https://creativecommons.org/licenses/by-sa/2.0/legalcode" target="_blank">CC BY-SA 2.0</a></em></p>
<audio id="player" controls="" type="audio/mpeg" src="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-1-24/418752236-44100-2-b54befa6b1d3c.m4a">
<a href="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-1-24/418752236-44100-2-b54befa6b1d3c.m4a">
Download audio
</a>
</audio>
<div>
<h2 id="news"> News
</h2>
<ul>
<li id="recent-op-return-output-statistics" class="anchor-list">
<p>
<a href="#recent-op-return-output-statistics" class="anchor-list-link">●</a>
Recent OP_RETURN output statistics
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('45:54')" class="seek">45:54</a><noscript>45:54</noscript>)
<a href="/en/newsletters/2026/02/20/#recent-op-return-output-statistics">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#recent-op-return-output-statistics-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-pipes-v2" class="anchor-list">
<p>
<a href="#bitcoin-pipes-v2" class="anchor-list-link">●</a>
Bitcoin PIPEs v2
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:33')" class="seek">1:33</a><noscript>1:33</noscript>)
<a href="/en/newsletters/2026/02/20/#bitcoin-pipes-v2">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-pipes-v2-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="changes-to-services-and-client-software"> Changes to services and client software
</h2>
<ul>
<li id="second-releases-hark-based-ark-software" class="anchor-list">
<p>
<a href="#second-releases-hark-based-ark-software" class="anchor-list-link">●</a>
Second releases hArk-based Ark software
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('20:21')" class="seek">20:21</a><noscript>20:21</noscript>)
<a href="/en/newsletters/2026/02/20/#second-releases-hark-based-ark-software">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#second-releases-hark-based-ark-software-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="amboss-announces-railsx" class="anchor-list">
<p>
<a href="#amboss-announces-railsx" class="anchor-list-link">●</a>
Amboss announces RailsX
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('55:35')" class="seek">55:35</a><noscript>55:35</noscript>)
<a href="/en/newsletters/2026/02/20/#amboss-announces-railsx">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#amboss-announces-railsx-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="nunchuk-adds-silent-payment-support" class="anchor-list">
<p>
<a href="#nunchuk-adds-silent-payment-support" class="anchor-list-link">●</a>
Nunchuk adds silent payment support
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('56:11')" class="seek">56:11</a><noscript>56:11</noscript>)
<a href="/en/newsletters/2026/02/20/#nunchuk-adds-silent-payment-support">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#nunchuk-adds-silent-payment-support-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="electrum-adds-submarine-swap-features" class="anchor-list">
<p>
<a href="#electrum-adds-submarine-swap-features" class="anchor-list-link">●</a>
Electrum adds submarine swap features
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('58:08')" class="seek">58:08</a><noscript>58:08</noscript>)
<a href="/en/newsletters/2026/02/20/#electrum-adds-submarine-swap-features">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#electrum-adds-submarine-swap-features-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="sigbash-v2-announced" class="anchor-list">
<p>
<a href="#sigbash-v2-announced" class="anchor-list-link">●</a>
Sigbash v2 announced
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('33:56')" class="seek">33:56</a><noscript>33:56</noscript>)
<a href="/en/newsletters/2026/02/20/#sigbash-v2-announced">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#sigbash-v2-announced-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="releases-and-release-candidates"> Releases and release candidates
</h2>
<ul>
<li id="btcpay-server-2-3-5" class="anchor-list">
<p>
<a href="#btcpay-server-2-3-5" class="anchor-list-link">●</a>
BTCPay Server 2.3.5
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:00:11')" class="seek">1:00:11</a><noscript>1:00:11</noscript>)
<a href="/en/newsletters/2026/02/20/#btcpay-server-2-3-5">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#btcpay-server-2-3-5-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="lnd-0-20-1-beta" class="anchor-list">
<p>
<a href="#lnd-0-20-1-beta" class="anchor-list-link">●</a>
LND 0.20.1-beta
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:01:43')" class="seek">1:01:43</a><noscript>1:01:43</noscript>)
<a href="/en/newsletters/2026/02/20/#lnd-0-20-1-beta">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#lnd-0-20-1-beta-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes"> Notable code and documentation changes
</h2>
<ul>
<li id="bitcoin-core-33965" class="anchor-list">
<p>
<a href="#bitcoin-core-33965" class="anchor-list-link">●</a>
Bitcoin Core #33965
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:02:55')" class="seek">1:02:55</a><noscript>1:02:55</noscript>)
<a href="/en/newsletters/2026/02/20/#bitcoin-core-33965">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-33965-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="eclair-3248" class="anchor-list">
<p>
<a href="#eclair-3248" class="anchor-list-link">●</a>
Eclair #3248
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:05:55')" class="seek">1:05:55</a><noscript>1:05:55</noscript>)
<a href="/en/newsletters/2026/02/20/#eclair-3248">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#eclair-3248-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="eclair-3246" class="anchor-list">
<p>
<a href="#eclair-3246" class="anchor-list-link">●</a>
Eclair #3246
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:07:08')" class="seek">1:07:08</a><noscript>1:07:08</noscript>)
<a href="/en/newsletters/2026/02/20/#eclair-3246">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#eclair-3246-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4335" class="anchor-list">
<p>
<a href="#ldk-4335" class="anchor-list-link">●</a>
LDK #4335
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:08:52')" class="seek">1:08:52</a><noscript>1:08:52</noscript>)
<a href="/en/newsletters/2026/02/20/#ldk-4335">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4335-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4318" class="anchor-list">
<p>
<a href="#ldk-4318" class="anchor-list-link">●</a>
LDK #4318
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:14:32')" class="seek">1:14:32</a><noscript>1:14:32</noscript>)
<a href="/en/newsletters/2026/02/20/#ldk-4318">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4318-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="lnd-10542" class="anchor-list">
<p>
<a href="#lnd-10542" class="anchor-list-link">●</a>
LND #10542
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:15:55')" class="seek">1:15:55</a><noscript>1:15:55</noscript>)
<a href="/en/newsletters/2026/02/20/#lnd-10542">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#lnd-10542-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bips-1670" class="anchor-list">
<p>
<a href="#bips-1670" class="anchor-list-link">●</a>
BIPs #1670
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:17:02')" class="seek">1:17:02</a><noscript>1:17:02</noscript>)
<a href="/en/newsletters/2026/02/20/#bips-1670">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bips-1670-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bolts-1236" class="anchor-list">
<p>
<a href="#bolts-1236" class="anchor-list-link">●</a>
BOLTs #1236
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:27:50')" class="seek">1:27:50</a><noscript>1:27:50</noscript>)
<a href="/en/newsletters/2026/02/20/#bolts-1236">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bolts-1236-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bolts-1289" class="anchor-list">
<p>
<a href="#bolts-1289" class="anchor-list-link">●</a>
BOLTs #1289
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:29:10')" class="seek">1:29:10</a><noscript>1:29:10</noscript>)
<a href="/en/newsletters/2026/02/20/#bolts-1289">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bolts-1289-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
</div>
<h2 id="transcription">Transcription</h2>
<p><strong>Mike Schmidt:</strong> Welcome everyone to Bitcoin Optech Newsletter #393 Recap.
Today, we’re going to be talking about some recent OP_RETURN output statistics
following Bitcoin Core’s v30 release; we’re going to talk about Bitcoin PIPEs
v2, and covenant-like enforcement without consensus changes; and we also have
our regular monthly segment covering recent Changes to client software that we
find interesting; and we have also our weekly Releases, release candidates, and
Notable code and documentation changes. Murch, Gustavo and I are joined this
week by three guests. We’ll have them introduce themselves briefly, and then
we’ll jump into the newsletter. Misha, who are you? Who are you, what do you
do?</p>
<p><strong>Misha Komarov:</strong> It’s Bitcoin Pipes, I guess the most relevant thing for
today’s conversation.</p>
<p><strong>Mike Schmidt:</strong> Excellent, thanks for joining us. Erik?</p>
<p><strong>Erik De Smedt:</strong> Hi, I’m Erik, I work at Second. We’re building an
implementation of Ark, and I’m going to talk about hArk, which is our new
variant of the Ark protocol.</p>
<p><strong>Mike Schmidt:</strong> And arbedout?</p>
<p><strong>arbedout:</strong> Hey, I’m working on Sigbash, which right now is a zero-knowledge
MuSig2 policy signer.</p>
<p id="bitcoin-pipes-v2-transcript"><em>Bitcoin PIPEs v2</em></p>
<p><strong>Mike Schmidt:</strong> Awesome. Well, thank you again for joining us. We’re going
to go a little bit out of order. So, if you’re following along at home, we’re
just going to have a little deference to our guests, and so bear with us as we
jump out of order. But we are going to jump to the News section first. We have
Bitcoin PIPEs v2. Misha, you posted to Delving Bitcoin about Bitcoin PIPEs v2,
a protocol for enforcing spending conditions without consensus changes,
including covenant-like instructions. Maybe, Misha, you can give us a quick
overview. What was, or is, Bitcoin PIPEs v1, and then what is v2; and then we
can get into some Q&A?</p>
<p><strong>Misha Komarov:</strong> Okay. Well, long story short, Bitcoin PIPEs v1 was published
October 2024, and it was all about, well, the attempt to enforce post-covenants
or like pre-covenants and post-covenants, what’s called pre-covenants and
post-covenants, without a soft fork or consensus changes, I mean kind of
externally. So, Bitcoin PIPEs v1, we’re focusing on trying to achieve this with
functional encryption. Functional encryption is, well, futuristic.
Conceptually, it’s how it should be. And it’s kind of the end game. The
question was all about, can we make this run faster? Can we make this run in
practice? Can we make this run in production? And what, a year, year and a
half later, v2 basically is all about that, is all about cutting out pieces here
and there, is about switching from functional encryption to witness encryption
which, spoiler, turned out to be still enough to enforce, I would say, the most
important covenants, like binary covenants and OP_VAULT, or like CSFS
(CHECKSIGFROMSTACK), I mean to emulate that effectively. It’s you know still
not very cheap to run, but come on, dude, that’s witness encryption! And over
the year, this went from, “Oh, it would be cool to run this sometime in the
future”, to, “Well, you can run this, you have enough storage”. So, this is
what it is. This is what Bitcoin PIPEs v2 is all about.</p>
<p><strong>Mike Schmidt:</strong> Maybe, Misha, you can help explain a couple things for us. I
think Jeremy Rubin, at some point, tried to explain to me functional encryption.
That was the first time I had heard of it. Can you touch on functional
encryption and witness encryption a bit for the audience?</p>
<p><strong>Misha Komarov:</strong> Yeah, okay. So, both of them are pretty much
obfustopia-level cryptographic obfustopia primitives. Functional encryption is
effectively a type of encryption scheme which allows you to decrypt and compute
certain things as the result over a ciphertext and the input you put through
there, only if the input satisfies a certain condition. So, this way, you can
define this condition, you can predefine this condition. So, effectively, it’s
kind of cryptographically enforcing a certain type of computation if a condition
is met. So, it’s a generalization of a public key cryptography, where the key
is not just kind of the bytecode, but a circuit or a truth over a certain
circuit even more. So, that’s functional encryption.</p>
<p>Witness encryption is a, well, I would say a more lightweight brother of this
kind of functional encryption idea. It doesn’t allow you to compute a
complicated function over a ciphertext to output something large, like 256 bits,
or whatever the amount of bits you want to output as a signature, right? But it
allows you to only output yes or no, effectively checking if the condition being
executed with a certain decryption algorithm over a ciphertext is true or not;
which means we can decrypt either 0, either 1, depending on if a certain ZKP is
correct or not; which means, well, turns out that it’s enough to enforce certain
covenants. So, that’s what it is.</p>
<p><strong>Mark Erhardt:</strong> So, basically you encode some predicates that allow you to
encode out-of-band conditions or criteria by which you want to lock up funds.
And all of that happens completely transparently or hidden, steganographically
basically, in the witness data. So, all of the heavy lifting is out of band.
And this works today?</p>
<p><strong>Misha Komarov:</strong> It works. Surprisingly, we think we can state that it works,
the witness encryption part.</p>
<p><strong>Mark Erhardt:</strong> So, you say that you can emulate certain covenants with this.
So, I guess, how would the average covenant user know that you’re actually
enforcing the right conditions out of band? They can’t really see what’s going
on under the hood. How would a person that just wants to use the covenant
approach this? Do they just trust you or is there more here?</p>
<p><strong>Misha Komarov:</strong> Yeah, absolutely. There is no need, or there is no idea for
somebody to trust anybody. We wouldn’t have spent a year otherwise doing the
work we’ve done. I’d say, okay, so the idea is that just like, I guess, back in
the day, the key mechanism wasn’t changed. Initially, during the setup of a
certain covenant, there is a setup procedure for the covenant. And of course,
we’ve got to be transparent in here, that there are like one out-of-band
assumptions there. So, you’ve got to set up a certain covenant, like you’ve got
to generate a private key in like a DKG so nobody would know that key. But of
course, the committee or whoever publishes the ciphertext on this key, you can
inspect and you can see what kind of circuit is required there for this
condition to be satisfied and the key to be unlocked. And it’s obviously also
kind of not required, but I would say it’s expected for a committee to at least
publish a public key of the keypair they’ve generated, I mean so people could
see that once there is a transaction signed by a private key corresponding to
that public key, it means somebody has done the computation correctly and there
is a transaction and it’s all valid. So, basically, that’s kind of the thing.</p>
<p><strong>Mark Erhardt:</strong> Okay, so the ability to sign for the transaction guarantees
that the predicate resolved to true, and therefore the conditions that were
encoded were met. And so, we trust in the setup procedure to some degree, but
other than that, if the setup was done correctly, we’re good.</p>
<p><strong>Misha Komarov:</strong> Nothing else can go south there. That’s the whole pitch.</p>
<p><strong>Mark Erhardt:</strong> Cool. Okay. Yeah, anyone else got questions? This sounds
like something that’s down your alley, arbedout.</p>
<p><strong>arbedout:</strong> Okay, this sounds incredibly interesting, and I really like the
idea that you don’t have to wait for consensus changes to be able to test this
out. I guess my first question is about, because this jumps out when you read
the paper, the 383 GB of data that is required. As a user, do I need to fetch
that and run a cryptographic operation on it?</p>
<p><strong>Misha Komarov:</strong> To be precise, it’s not 338 GB. Right now, at the time of
the first release of the Arithmetic Affine Determinant Program (AADP) witness
encryption with done, it’s 338 TB, which is too much, obviously, yes. But
again, we kind of calm ourselves internally that come on, dude, this is the
first witness encryption out there! So, it’s already good enough that we can
run something. But we think we know, and there was a little bit of a banter in
the chat recently, we think we know how to reduce this to around 100 GB in terms
of ciphertext size. Once we prove it’s secure, because we don’t have a formal
proof of that reduction in terms of security, we’ll publish that as well. It’s
going to be like 100 GB per ciphertext. So, effectively, it becomes similar to
what people do with garbled circuits, it becomes pretty close to what people do
with garbled circuits. That’s what it is.</p>
<p>In terms of, is a user expected to download the whole thing? I mean, you can,
but can you outsource part of that computation somewhere? Yes, that’s the whole
thing. You can outsource it to somebody who has enough computation capacity, or
you can outsource, I don’t know, a significant part of it to somebody who has
enough storage capacity. And I would say again, there is a mention of this in
the paper, but we think that as a way to batch a lot of keys into a into a
single ciphertext. So, you could generate like several 100 or maybe 1,000, if
you wanted more keys inside a single ciphertext, and then decrypt, decrypt,
decrypt up to a certain limit. I mean, of course, after a certain limit, it
becomes not really secure. But up to a certain limit, you can keep this secure.
And this way, you don’t need 100 GB per key, you basically need like 100 GB for
a certain amount you have batched inside. So, that’s kind of how it looks right
now. But we wanted to be a little bit more conservative and put it out
experimental and speculative stuff. I mean, we can talk about it like this,
right? But when you put out the paper, you claim something, you’d better claim
something which you know works.</p>
<p>So, we know right now that this 338-TB thing is secure, more or less. We
weren’t able to crack it. Anybody we consulted with wasn’t able to crack it.
We spent significant time trying to crack it. We will be doing public
challenges, we will be going around and we will lock some bitcoin behind some
ciphertext, behind some key, we will be like, “Okay, well, whoever breaks it
gets some bitcoin”. I mean, if you can retrieve the key, absolutely do it. So,
that’s just for the sake of making sure that this doesn’t fall apart. But yeah,
that’s the situation there right now.</p>
<p><strong>Mike Schmidt:</strong> Misha, we covered that you posted in Delving. I believe you
or someone else also posted to the Bitcoin-Dev mailing list as well. What’s
reception been so far?</p>
<p><strong>Misha Komarov:</strong> Well, I mean, Delving Bitcoin, as you might have notice, we
haven’t seen anything negative. I mean, there is interest, obviously. There is
quite a lot of, I would say, positive reception. Well, not very excited, of
course, because when people hear a phrase, “Witness encryption, and you can run
that”, everybody gets like, “What?” But in general, we haven’t seen negative
feedback. We’ve seen a lot of suspicion and we had to answer a lot of
questions. It’s okay, it’s good. We’ve seen a lot of positive results. So, it
was like I said, seen positive reactions from, well, specifically from BitVM
guys. We are yet to go around a little bit and to try to specify certain opcode
proposals, which were specified inside certain BIPs over time, like OP_VAULT. I
mean, we know that it will deprecate, right? But if we could do an analogous to
an OP_VAULT, I mean, anybody would mind? I don’t think anybody would mind.</p>
<p>So, we’re yet to specify how certain BIPs, which we’re interested in, which are
still interesting, over time can be expressed and can be replaced or can be
substituted or emulated with PIPEs. We will be trying to go around relevant,
certain authors of BIPs, and then we will be trying to be like, “What do you
think? I mean, maybe this can work today”. Like, this is one more thing we’re
yet to do. There might be something for us also to talk about with, besides
BitVM guys, to lightning folks, I mean because there’s always a little bit of a
thing liquidity on the receiver side fragmentation, right? So, if you have
OP_VAULT, or if you have some kind of vault, you could probably reduce that kind
of channel liquidity fragmentation there. That’s a little bit of improvement
there. What else is there? Yeah. I mean, we could probably go around some
folks who try to do privacy-preserving Bitcoin transactions. That would be
interesting. Maybe we could improve Shielded CSV through that somehow. That is
a couple of ideas it all comes down to basically, yeah.</p>
<p><strong>Mark Erhardt:</strong> You mentioned BitVM a few times. So, my understanding is that
BitVM allows you to encode these circuits, and then it’s sort of optimistic in
the sense that they publish and if you find a mistake, you can challenge and you
have to publish big chunks of data, and then you can take the money. It sounds
that your PIPEs are similar in what you can do with them, but the system works
rather with the zero-knowledge proof out of band. So, there’s no taking or
slashing. Is that roughly correct?</p>
<p><strong>Misha Komarov:</strong> It’s pessimistic and single transaction and non-interactive.
That’s the whole kind of pitch, yeah.</p>
<p><strong>Mark Erhardt:</strong> Okay. Is there other aspects that you would say are important
to compare or show the differences?</p>
<p><strong>Misha Komarov:</strong> I mean, of course, maybe for now, one of the obvious things
for now, maybe the costs of storage are higher than what BitVM folks have right
now, right? Of course, there are kinds of nuances about how BitVM constructions
in general manage the kind of reorg risks because of probabilistic finality,
which it’s much easier for BitVM to handle that, because it’s optimistic,
interactive, people are kind of okay-ish with that. On the bright side, like on
the upside side, with PIPEs, well, if PIPEs were to be used as a foundation for
some kind of bridge, or this kind of stuff like the BitVM people do, this would
remove the operator liquidity requirements. It would remove, I think, quite a
lot of interactivity. I mean, it would remove the liveness risk, because the
whole decryption process is basically not interactive. If the setup is done
correctly, then nothing can prevent you from just taking your bitcoin back if
something goes south, or whatever. You can call it an escape hatch, if you want
to. So, this kind of stuff.</p>
<p>Yeah, I mean, what else is there? And of course, if you want to compare the
waiting period in terms of you’ve got to wait for somebody to submit a fraud
proof or this kind of stuff, well, there’s nothing like this in here. Once it’s
decrypted, it’s decrypted, it’s there, the transaction is done. So, this is the
attestation.</p>
<p><strong>Mike Schmidt:</strong> Well, I think in those last comments that you made, Misha, I
think listeners, depending on what they do in Bitcoin, may have a call to action
to either check out the Delving post or reach out to you if there’s something
they think is worth emulating or have questions. Anything else you’d have as a
call to action for listeners?</p>
<p><strong>Misha Komarov:</strong> I mean, we are looking to obviously as much feedback as
possible. We are going to be looking for people willing to try to crack this.
I mean, it will be open challenges. So, if you’re a cryptographer person, or
whatever, don’t hesitate to take a stab or, you know, we will be doing
challenges about this. If you have ideas or you have good suggestions on which
BIPs also could use help of emulation via PIPEs, I specifically called for that
feedback, for those suggestions on Bitcoin-Dev mailing list a couple of days
ago, maybe yesterday, whatever.</p>
<p><strong>Mike Schmidt:</strong> Great. Well, Misha, thank you for joining us. We appreciate
your time and if you have other things to do, you’re free to drop. Cheers.
We’re going to jump to the Client and services segment and talk about a couple
of items before jumping back up to the news.</p>
<p id="second-releases-hark-based-ark-software-transcript"><em>Second releases hArk-based Ark software</em></p>
<p>We’re going to talk about Second releasing a hArk-based Ark software. This is
in v0.1.0-beta.6, and we have Erik on who’s going to walk us through, maybe
reminding us what Second is working on with Ark; and then, also jump into what
is hArk and how does it reduce some of these interactivity requirements we’ve
heard so much about.</p>
<p><strong>Erik De Smedt:</strong> Okay, cool. So, yeah, at Second we’re building hArk. It’s
an Ark implementation and basically, we’re just focused on sending and receiving
bitcoin, very straightforward and get user experience very well for users on
mobile, their phones, web browsers, not having to run a full node all the time,
to run a reliable wallet where you have some good sense of custody. We started
building the Ark protocol as it was initially invented. And basically,
especially for mobile phones, we ran a little bit into a problem. So, the core
concept of Ark is basically, in Ark, you hold vTXOs and your vTXO is a bit like
Bitcoin UTXO. The only difference is it’s an output of a transaction that isn’t
onchain yet. You just have a chain of transactions, and in the best case, you
have a signature in the entire branch in that chain. You can broadcast these
transactions and you’re guaranteed that you can get your transaction onchain if
you need to. It comes with a little bit of a trick, like this guarantee
expires. After some point, the Ark server can basically sweep the coins, which
gives the Ark server the liquidity back, which is in the UTXO. And to prevent
it, you need to participate in a round. And basically, what you do is you take
your old vTXO, you forfeit it, and you will get a new vTXO in return. And
that’s basically the idea of participating in a round.</p>
<p>That process works quite well, but for mobile phones especially, it has one big
problem. So, basically, the Ark server will host a round and let’s say it will
do it at 1.00pm sharp. Everyone who wants to participate in that round needs to
be online at 1.00pm sharp. And we noticed, especially for mobile phones, that’s
a huge problem. You have some APIs to schedule a phone to wake up or send
notifications to the phone that they should wake up, but most of these things
are somewhat unreliable because smartphone manufacturers want to preserve
battery. And we can say, “Please wake up at 1.00pm”, but if you’re unlucky, it
wakes up at 1.00pm and 30 seconds, and your phone has missed a round in the
refresh field, or it might not even wake up at all. So, that’s pretty terrible.</p>
<p><strong>Mike Schmidt:</strong> And, Erik, what are the consequences if there isn’t a wake-up?</p>
<p><strong>Erik De Smedt:</strong> So, basically if you don’t wake up, the phone will not
refresh the coin, and basically the old vTXO will expire. And at that point,
you get in a situation where both you and the server could basically take the
money. But at some point, the server actually has to take the money, because
they need their own money back. It’s in the same output. So, basically, you
lose custody of your coins, which is very bad. That’s something we want to
avoid at any cost. So, what we’ve been trying to do is, how can we make sure
that not all the phones need to be online at exactly the same time? And it
turned out that the solution is ridiculously obvious. So, in the round
protocol, which initially was a little bit convoluted, but basically there are
three steps in it. So, the first one is if a round starts as a phone, you go
and say, “Hey, I want to participate in a round. I have these vTXOs, I want to
get rid of this. Give me a new one basically to sign up”. Then we have the
co-sign phase, where basically you sign your branch of transactions. Ark works
with pre-signed transactions, it’s some construction thing. And then you have
the last phase, which is a forfeit, which is actually what we’re diving in now.</p>
<p>Previously, we used a construct called connectors. It’s kind of weird, but the
core idea is that your forfeit transaction will have two inputs. So, one from
the vTXO, which is forfeited, and basically that’s the transaction where I say
as a client, “I give up my old funds”. But the forfeit also has another input,
and that goes back to the new round, which will give me the new vTXO. It’s a
little bit confusing. But if you do that, at that point, basically as a client,
you’re guaranteed that if you sign the forfeit, it will only be valid if you get
a new vTXO in return. And the reason why it used connectors is actually because
the server, when it creates the new vTXOs, it needs to create a funding
transaction and it needs to put a round of money in. And basically, it also
gives the same guarantee for the server, like you don’t need to fund around
before you’re sure all the old ones have been forfeited. And for a while, we
thought that was super-important and you had to do it like that and hashlocks
didn’t work. But actually, that seems to be false. So, what we now did is we
basically switched the order.</p>
<p>So, what will happen is the server will first fund around, and you think that
sounds dangerous, but we can ignore that for a while. And then, at a later
point in time, the server or the clients can come online, sign the forfeits and
basically do it whenever they see it fits. And if they come online two hours
later, fine, they can sign the forfeits and go through.</p>
<p><strong>Mark Erhardt:</strong> Does that work with a similar construction as the connector in
the sense that only if you sign away the forfeit, you get your new vTXO?</p>
<p><strong>Erik De Smedt:</strong> Basically, we now use hashlocks just like Lightning does it.
So, you sign now a forfeit transaction and that forfeit transaction gives the
server the coins if it releases a hash in time. So, basically, we now just use
the standard hashlocks very much like Lightning works. So, it’s much closer how
Lightning works and pretty well understood. And it’s actually also safe for the
server, because the fact that you have a vTXO is kind of already a dust
prevention for the server, like you can’t sign up without owning a vTXO, so the
server has control on how much money it will put in the new round. It’s turned
out to be surprisingly simple. Our code became a lot smaller, clearer and
easier to understand when developing this.</p>
<p><strong>Mark Erhardt:</strong> So, does this change anything about the amount of liquidity
that is necessary for each round?</p>
<p><strong>Erik De Smedt:</strong> It doesn’t change anything at all. So, the liquidity
requirements stay exactly the same. So, protocol-wise, there’s not that much
that changes. It also doesn’t really change the trust model, at least not for
clients who can stay online. So, if you’re like a server and you can be online
at the time of the round, it doesn’t change the trust model, but it allows
basically a fix for mobile clients who are not guaranteed to be online. We had
the three phases, so the sign-up, which was the first phase, and we had the
co-signing phase. If you run a node on a computer, which is always online,
you’ll do the co-signing yourself and you will get the best security model. If
you’re a mobile client, you can ask others to co-sign for you. So, the
co-signers will sign, they’ll forget the key, so you get forward security. It’s
just all pre-signed stuff. And that way, the mobile client doesn’t have to be
online at the round, it can come online later and sign the forfeit when they
want to.</p>
<p><strong>Mike Schmidt:</strong> Is the co-signing aspect here sort of a trade-off with this
new approach?</p>
<p><strong>Erik De Smedt:</strong> Yeah, it’s a trade-off, but it’s fully optional. So, the way
it’s implemented, if you don’t want the co-signing, you can still do it
self-signed. But if you fail to co-sign, you can say, “Other people are allowed
to co-sign for me”. Even as a mobile client, how it’s currently implemented is
basically you try to co-sign yourself. If it fails, you fall back on the other
methods. Oh, go, Schmidty, sorry.</p>
<p><strong>Mike Schmidt:</strong> Oh, yes, sorry. I was going to ask, I’m curious what the
other Ark implementations think of this approach. Is this something that
everyone’s going to be moving to? Is this something that Second has a strong
opinion on and others differ? Maybe just add some color there.</p>
<p><strong>Erik De Smedt:</strong> I haven’t gotten much responses there from the other teams.
I know we basically were pretty close to launch, but then we came on this idea
and it was like, “Hell, no, we’re not going to build it while we have people
live on our system”, because you’re like doing open-heart surgery on the
protocol. And if you have live users, it will be very hard. So, I think once
you have an existing user base – the engineering challenge of switching was
already hard. I can only imagine it to be harder if you have to stay
backward-compatible for all the other users, because it’s not backward
compatible at all. I know other implementations have been looking at different
approaches. They call it delegated refreshes, where basically you ask someone
else to participate in the round on your behalf. The latest I know, it’s
written in blogpost, but not in code, so it’s not implemented yet.</p>
<p>I actually think the hArk model is better, because with the hArk model, it
actually comes with a few benefits. So, the first one is if you rely on other
co-signers, let’s say if we have ten co-signers, all ten of them can co-sign
your vTXO, and you’ll get additional security from all of them. So, that’s
definitely a win. It’s not like that you just have the one guy you delegated to
do it, which is one thing which is really nice. But also, a bit a downside of
the delegated model is basically, for your refresh to succeed, you need a server
to be online, like that’s a hard thing because he needs to fund a new round.
But you also get, like, if you delegated to a third party, that third party
needs to be online to go to the server and say, “Hey, this guy allowed me to
participate in the round”; while if you just go to the server, “I want to
participate in that round just before expiry”, you require less parties and you
can say, “If one of these co-signers is online, it’s good”. So, it also can
give you a very robust model where you don’t have to rely on too many other
people running services for you, because we see that might become a bit of a
reliability bottleneck.</p>
<p><strong>Mike Schmidt:</strong> For listeners who want to try this out, we highlighted that it
was 0.1.0-beta.6. Is this something that people can download and play with on
signet, or how do you recommend people try this out?</p>
<p><strong>Erik De Smedt:</strong> I would recommend you to download it, play on signet. If you
go to signet.2nd.dev, there’s a demo environment, there’s a faucet where you can
request Ark coins, you can make Lightning payments, onchain payments to a dummy
store. If you use that, you can use it. We have a CLI, we have barkd with a
Rust API. So, on signet, you have quite a lot of things to play with.</p>
<p><strong>Mike Schmidt:</strong> Excellent, Erik. Anything else for the audience before we
wrap up this item?</p>
<p><strong>Erik De Smedt:</strong> No, thanks. Thank you very much.</p>
<p id="sigbash-v2-announced-transcript"><em>Sigbash v2 announced</em></p>
<p><strong>Mike Schmidt:</strong> All right, Erik. Thanks for your time. Thanks for joining
us. We have a guest for another of our Client and service items. This one was
titled in the newsletter, “Sigbash v2 announced”. And we have arbedout here to
talk about Sigbash and Sigbash v2, which now uses MuSig, WASM, and ZKPs.
Arbedout, we covered Sigbash v1, I don’t know when it was, a couple years ago or
whatnot. It seems like you’ve been hard at work at it. It feels like a cool
project that I think people should be aware of, so I wanted to get you on to
talk about it. Maybe talk about Sigbash and then we can get into v2 as well.
What have you been up to?</p>
<p><strong>arbedout:</strong> Thanks, I really appreciate that. So, I’ll cover v1 briefly, I
guess. V1 was a policy signer that used standard ECDSA, which doesn’t really
afford you much opportunities for privacy, just the nature of the beast. It
leveraged blinded xpubs, and the idea behind those is that we had the client
JavaScript deriving child keys using random paths from a master key that our
servers provided. What that means is that users were given keys that the server
didn’t know about up until signing time came around. And once signing time
comes, of course, the server sees all of your transaction details still, because
it’s ECDSA and PSBTs, the key itself as well. Basically, you had privacy up
until you actually needed to use the server. Now, that’s a quantum leap ahead
of how normal signing works right now, where right off the gate, every member of
your ECDSA quorum sees your transaction balance and your entire history and
everything from the word go, even if you don’t ask them to sign. But it’s still
not great.</p>
<p>So, the past couple of years, I’ve been exploring whether we could improve on
that model at all. And what we’ve come up with is v2, which uses, like you
said, MuSig2, WASM, taproot, all that good stuff. I’ll talk through the
high-level flow of it, and then we can dig into questions. So, you start off by
defining a signing policy, and that signing policy can be just about any
property of a PSBT, the inputs, the outputs, the amounts, the pubkeys, and it
can be as complex as you might like. We take that policy, encode it into a
boolean abstract syntax tree. So, all the logic gates you might remember from
CS101 AND, OR, XOR, NOT, everything that you might need to express a policy. We
take that tree, walk it, and then turn that into a Sparse Merkle Tree, which I
know bitcoiners love, take the root node of that Sparse Merkle Tree, and just
send that single 32-byte hash to the server. So, for all those transformations,
the only thing our server sees is that single hash. It doesn’t know anything
else about your policy. And obviously, you can’t really infer anything about
the policy itself from that hash.</p>
<p>Next, we create a key entirely in WebAssembly on the client side by fetching a
key from our server, generating a new key on the client, aggregating the client
side with MuSig2, and storing an encrypted blob on our servers. So, from
beginning to end, from when you generate a policy to when you ask to sign a
policy, we never see your key, we never see your transaction, we don’t even see
the sighash (signature hash) of the message being signed.</p>
<p><strong>Mike Schmidt:</strong> Very cool. I’m curious, like, I’ve seen some of the social
media discussion, I’ve seen you post about this. Is this a service that is live
that you are providing now, this co-signing service?</p>
<p><strong>arbedout:</strong> It is live right now. You can go on sigbash.com and start paying
your way on the web app right now. You don’t have to download and install
anything. That’s the great thing about WebAssembly. Right now, it’s live on
signet. If you go looking, you can figure out pretty quickly how to go live on
mainnet. Maybe give us a couple of weeks before you do that. We’re still
making sure there are no bugs. I have fond memories or not so fond memories of
someone on v1 immediately locking up about $5,000 in sats in a key that we had
to struggle to help them send. I don’t think we have any bugs this time around,
but give us a little bit before you try on mainnet.</p>
<p><strong>Mike Schmidt:</strong> And is this open source? Are you providing this as sort of a
company and you’re charging for this service, or how does it work in that
regard?</p>
<p><strong>arbedout:</strong> So, my plan is, and this is still loose, so bear with me, don’t
hold me to this, but I think the web app is going to be free as long as I can
manage that. It is a company, we are incorporated, but I think for that level
of integration, we need an SDK, which is what we’re working on. We’re talking
to partners right now at exchanges, at custodians, anyone who is currently
handling signing or signing adjacent, whether it’s multisig or watch-only
wallets. We’re probably going to be focusing on the SDKs, the commercial
enterprise, and the web app will be for all the crazy mountain-men node runners
who want to use it.</p>
<p><strong>Mark Erhardt:</strong> So, you said that the server doesn’t even see the message that
is being signed. Are you referring to the transaction itself at this point with
message?</p>
<p><strong>arbedout:</strong> Yeah, the transaction.</p>
<p><strong>Mark Erhardt:</strong> So, it’s completely blinded to the server; the server is
enforcing the policy that you committed to when you created it and signs off on
it when the policy is fulfilled, but doesn’t even know which transaction it
signed?</p>
<p><strong>arbedout:</strong> That’s correct. So, under the hood, what that looks like,
remember the server sees that root Sparse Merkle Tree, a hash? What the client
in WebAssembly submits, you as a user upload your PSBT, WebAssembly parses that
PSBT. Providing that your PSBT matches one of the clauses of the policy that
you defined, it will submit a proof bundle consisting of a path leaf with the
merkle inclusion proof proving that that path belongs to your original root
hash; a zero-knowledge proof proving that you know the inputs that can create
that path leaf; and a very small schnorr proof of knowledge, tying it to the
sighash, the message being signed. So, end-to-end, you know, okay, this person
has a PSBT that must be able to create these inputs, and that PSBT must be tied
to a valid transaction.</p>
<p><strong>Mark Erhardt:</strong> Sorry, I’m confused. So, you provide a PSBT of the
transaction?</p>
<p><strong>arbedout:</strong> On your side, and then, from there on, WebAssembly is parsing it
and providing, basically proving that you have a PSBT that semantically meets
the policy that was originally defined.</p>
<p><strong>Mark Erhardt:</strong> Oh, the WebAssembly side sees the PSBT; the server does not
see the PSBT?</p>
<p><strong>arbedout:</strong> Yeah.</p>
<p><strong>Mark Erhardt:</strong> Okay, that’s what I was missing. Okay. I was like, if you’re
sharing the PSBT, you still see the transaction, just with extra steps. But
yeah, okay. So, only the client side has the PSBT. Okay, cool.</p>
<p><strong>Mike Schmidt:</strong> Well, I guess the call to action for listeners is pretty
straightforward. Come play with this thing, right? Is there anything else,
arbedout, that you want people to know?</p>
<p><strong>arbedout:</strong> The nature of Sigbash v2 is that once it launches on prod, it’s
set in stone. So, please bang on it and let me know if there are any features
we’re missing. Just like Erik said, it’s very difficult to have two different
versions of proof bundles, for example. So, if there are conditions that you’re
saying that are missing, please let us know. We’ve implemented everything from
the basic stuff, like inputs and outputs and pubkeys and amounts, to more
complicated stuff, like covenant emulation. But if there’s anything we’re
missing, give us a shout.</p>
<p><strong>Mike Schmidt:</strong> Awesome, arbedout. Oh, go ahead, Murch.</p>
<p><strong>Mark Erhardt:</strong> Yeah, I feel like we’re talking about very much similar ideas
a lot lately. So, BitVM, the PIPEs previously, Sigbash. Someone recently asked
me to read something in the comments on our tweet that was also sort of encoding
functional functions. So, is this just taproot coming to roost; after taproot
being out for four years, people have had time to bang on the pot? Or what
makes all of you come out with your projects at the same time?</p>
<p><strong>arbedout:</strong> Speaking only for myself, I think definitely part of it is just it
takes time for tooling to be implemented. A lot of what I built with Sigbash v2
required the upstream libraries to implement MuSig2 support and taproot support.
And then, there is obviously a learning curve trying to think about, “Well, what
can I do with this? What is now possible?” And then there’s a sort of second
level. Once you start seeing that initial trickle of other projects working on
things, that you draw inspiration from that and start thinking, “Oh, well, zero
knowledge, what can I do with this?” In the case of at least the zero-knowledge
side of things, again I’m speaking only for myself, but I sort of can infer this
from comments other people have made, there’s a pretty influential paper that
was released about two years ago called, Concurrently Secure Schnorr Signatures,
where the authors proved that the idea of zero knowledge predicates and how that
might work in theory with schnorr sigs. And I remember Jonas Nick tweeting that
out, and then a bunch of different projects latching on to that and starting to
have discussions, “Well, zero-knowledge covenant-ish type things, what can we do
with this?”</p>
<p>I think it sort of is time, but it’s a combination of time passing and then
people experimenting, and then other people getting ideas from those
experiments. And then it’s just a slow-moving avalanche.</p>
<p><strong>Mark Erhardt:</strong> So, it’s just the ideas floating around and then basically
infecting each other until something falls out. And there’s like four or five
different things that are very similar that have different trade-offs and now,
yeah, I guess we’re getting all of them!</p>
<p><strong>arbedout:</strong> Yeah, I promise we don’t have some like pseudo covenants dragon’s
den slack room that we’re all meeting in to talk about this. It’s all actually
organic. It’s interesting, both for PIPEs and I think there’s that other
project, BLISK, that announced a couple of weeks ago. They’re very similar
orthogonal ideas and you can see none of us have communicated with each other.
It’s all after the fact, we’ve been DM’ing like, “Oh, wow, this sounds very
interesting. We seem to be on the same wavelength”, but it’s completely
organic.</p>
<p><strong>Mark Erhardt:</strong> Talking about covenants. So, all of, or not all of you, some
of you are basically emulating covenants. And what if we actually introduce
some of these opcodes into Bitcoin any decade now?</p>
<p><strong>arbedout:</strong> Speaking only for myself, I would love that. I think just from
the co-signing point of view, if you’re using a co-signer to emulate covenants,
you either didn’t need covenants or you’re making do with something that
probably isn’t purpose-suited for you. The difference is the trust model.
Covenants, when enforced by consensus, are guarded by the Cyber Hornet crowd.
It’s onchain and public, and everyone’s nodes are enforcing it. What we’re
doing is offchain, private, and you’re not really trusting the co-signer because
the co-signer doesn’t see anything. They can’t be censoring you based on
transaction contents that they can’t see, but you are trusting them to be online
and to sign things dutifully. It’s a radically different trust model. From my
point of view, if covenants were to go live tomorrow, I think we’d start
building all sorts of cool new features on top of that, and I’m sure the PIPEs
guys would say the same thing as well. As much as I would like to think
otherwise, there is no pool of Bitcoin users waiting and hoping, “Oh, I’m going
to write Bitcoin Script by hand for my transactions and these opcodes will slide
into it”. It’s the builders like us that are actually going to make use of
those opcodes.</p>
<p><strong>Mark Erhardt:</strong> Thanks for the perspective.</p>
<p><strong>Mike Schmidt:</strong> Very cool. Thanks for joining us and hanging on through the
first half of the newsletter, arbedout. You’re welcome to drop a few other
things to do.</p>
<p><strong>arbedout:</strong> Thank you for having me.</p>
<p id="recent-op-return-output-statistics-transcript"><em>Recent OP_RETURN output statistics</em></p>
<p><strong>Mike Schmidt:</strong> Cheers. Jumping back up to the newsletter, we had our first
News item, which was titled, “Recent OP_RETURN output statistics”. And we
covered AJ Towns’ post to Delving Bitcoin about analysis that he did on
OP_RETURN usage since Bitcoin Core v30 was released, which was October 10th, I
believe. And he has his analysis, but he also linked to analysis from a couple
of other people, orangesurf, and also, Murch. Murch is obviously here and has
done some of the analysis hands-on and read both of the other analyses. So,
Murch, what should we take away from this? Well, I guess, what was found, and
then we can get into takeaways?</p>
<p><strong>Mark Erhardt:</strong> So, I think the context of this is people making arguments
about the amount of OP_RETURN outputs we’ve been seeing, and maybe also putting
that in the context of what would be allowed, given some soft fork proposals
activating or not activating. It’s just giving the raw numbers on that. So, AJ
has looked at some 20,000 blocks or so, 20,200, I think. And in those blocks,
he found 24 million OP_RETURN outputs. And out of those transactions, 24
million transactions with OP_RETURN outputs, 460 either had multiple OP_RETURN
outputs or oversized OP_RETURN outputs, where oversized means 84 bytes or more.
So, 24.3 million transactions with OP_RETURN outputs, 460 are affected or
subject to the new OP_RETURN policy by Bitcoin Core. So, most of these would
just be completely unaffected, would not have changed their behavior at all if
the policy change in Bitcoin Core v30 hadn’t been made. And maybe also, to make
it very clear, 24,360,000 of those transactions minus 400 would also be in
reduced data, temporary soft fork chain, because they’re compatible.</p>
<p>So, altogether, AJ found that there were about 474 MB of OP_RETURN data in these
20,200 blocks. And of that, I wrote it out.</p>
<p><strong>Mike Schmidt:</strong> Now we have the ‘explicit’ tag on Spotify. Thanks, Murch.</p>
<p><strong>Mark Erhardt:</strong> 2 MB. 2 MB of that were oversized or multiple OP_RETURN
outputs. So, out of 474, 2 MB were affected, or could have been affected by the
mempool policy change for large OP_RETURNs in v30. So, this is a tiny portion.
I think anyone still making the argument that OP_RETURN has been used a lot more
than it was before, I think it has been minusculely used more. There are a few
more transactions, but in volume, I looked at this data myself, I published a
dashboard on dune.com that aggregates the OP_RETURN data per week. And the
dashboard showed me that there were about, well, a similar amount of
transactions and data bytes in OP_RETURN outputs before v30. And especially
also, oversized OP_RETURNs have not changed significantly.</p>
<p>So, the facts themselves, they are hard to argue with because they’re facts, but
the interpretation that I have is that the OP_RETURN policy did not
significantly change the usage pattern of this on the network.</p>
<p><strong>Mike Schmidt:</strong> And, Murch, I don’t know if it was your analysis or some other
comments that I’ve seen, but there was actually a spike, well not a large spike,
but there was a few oversized OP_RETURNs that happened about a year ago before
the release, right? Just mostly around, I don’t know, the discussion of large
OP_RETURNs, like people playing around with it.</p>
<p><strong>Mark Erhardt:</strong> I mean, a bunch of people went around and claimed that
oversized OP_RETURNs were hard about a year ago. In April, when the policy was
debated whether or not the OP_RETURN mempool policy still has teeth and does
something useful, a few people, especially those that were against the change in
Bitcoin Core, made the argument that it was essentially impossible to do before.
So, I think this spurred a bunch of people that just felt the need to show that
it was incorrect to say so, to make a lot of oversized OP_RETURN outputs. So,
the biggest spike in the last couple of years actually was April last year, when
there were, I think, some 10,000 or so oversized OP_RETURN transactions, just to
demonstrate that it was completely possible to do. And yes, so the debate
basically provided parallel proof just how loose that policy was already, how
little enforcement it got. Yes, only a few miners were including those
transactions at that time. But unless you’re urgently trying to get your
transaction in, it only takes a few miners to include it to get 100% of those
transactions in.</p>
<p>So, I think it succeeded in demonstrating that the policy was not very useful
anymore at that time. And especially in the context that the inscription
envelope being cheaper for large amounts of data anyway, and being standard and
being widely deployed, continuing to enforce the OP_RETURN limit in order to
forbid a use case that naturally already was not incentive-compatible, except if
people were putting data in payment outputs, which was slightly more expensive,
just didn’t make sense. So, I think that our argument that we made as Bitcoin
Core developers back then still stands. There is no big economic incentive to
use large OP_RETURN outputs because people are going to use the inscription
envelope instead. And for people that use payment outputs to stuff data,
OP_RETURN being slightly cheaper and now allowing more than the 83 bytes per
transaction, actually allows them to use the OP_RETURN output instead of putting
data in payment outputs. And I don’t think it’s controversial that putting data
into payment outputs is worst kind of data embedding.</p>
<p>So, the inscription data will not move to OP_RETURNs just as predicted, and
hopefully some of the payment data will move to OP_RETURNs, where it’s less
harmful. So, I don’t know.</p>
<p><strong>Mike Schmidt:</strong> In any of these analyses, are you aware of categorization of
the small number of OP_RETURNs that do exist, like into buckets other than just
truly arbitrary content? Like, obviously I can put, “Mike is the greatest”,
piece of content in there and that’s just arbitrary content, but also people try
to structure their data and create these protocols. Like, is there anything
other than just people putting in arbitrary stuff?</p>
<p><strong>Mark Erhardt:</strong> I’m not aware of anyone having done further analysis than just
on size so far. But yeah, I think most of them are probably text at this point.
We’ve seen, just as AJ found some 400 or so oversized OP_RETURNs, which is not a
lot, sure there’s probably a couple of pictures in there too and something else,
whatever. But yeah, I’m not aware of anyone actually having done the whole
analysis. Orangesurf has published a report for mempool.research. I did
briefly skim it. I don’t think it went into this aspect either, but if any of
us three, it would be in there.</p>
<p id="amboss-announces-railsx-transcript"><em>Amboss announces RailsX</em></p>
<p><strong>Mike Schmidt:</strong> That wraps up the News. We’ll jump back to the Changes to
services and client software segment. We have three others that we didn’t touch
on. One was Amboss announcing RailsX, and this is a platform built on LN and
using taproot assets to support financial services, including things like
high-frequency trading or swapping between, let’s say, Lightning bitcoin and a
stablecoin, or some such thing that’s on taproot assets. And we link to their
post that outlines what they’re looking to build or have built already. So,
check that out if you’re interested. Gustavo or Murch, anything?</p>
<p id="nunchuk-adds-silent-payment-support-transcript"><em>Nunchuk adds silent payment support</em></p>
<p>We highlighted some support for silent payments from Nunchuk. So, Nunchuk added
support for sending to silent payment addresses. I don’t believe that Nunchuk
supports actually creating a wallet that can receive silent payments, but you
can send out of your Nunchuk wallet to a silent payment address. So, that’s
pretty cool to see that building support for silent payments over time.</p>
<p><strong>Mark Erhardt:</strong> Also, maybe sending to silent payments is a little
complicated, but it doesn’t require that special scanning, or all you need is to
know all of the inputs and the recipient you’re trying to pay, and then you can
construct the correct silent payments output. So, sending support is quite
achievable by pretty much any wallet. If you want to receive, it gets a little
more complicated because you need that special scanning mode, where you
construct a shared secret from the input public keys and your own private key
and compare that to all P2TR outputs. So, especially on light clients, that is
a bit of a heavier lift.</p>
<p><strong>Mike Schmidt:</strong> And we dove pretty deep with Craig Raw recently and talked
about some of the challenges of scanning. I think last week you guys had
Sebastian on also talking about scanning. So, if folks head to the podcast list
for Optech, look for the one last week, which would be #392, and then also
cruise back for the most recent Craig Raw one, where we talk into some of the
challenges with that. It’s definitely not prohibitive for wallets to implement
that, but there are some interesting challenges and it’s not quite as easy, as
Murch outlined, in terms of sending to a silent payment address.</p>
<p id="electrum-adds-submarine-swap-features-transcript"><em>Electrum adds submarine swap features</em></p>
<p>Last piece of software we highlighted this month was Electrum adding submarine
swap features in Electrum 4.7.0. I think they had some submarine swap features
previously, but in 4.7.0, using Electrum you can now pay onchain using your
lightning balance. This is the notion of submarine swapping. That’s the
feature that we highlighted from this release, but there are many other features
and fixes in this Electrum version as well if you’re curious.</p>
<p><strong>Mark Erhardt:</strong> Wait a second, so submarine payments, I knew that as having an
onchain payment as the last hop, like in a multi-hop HTLC (Hash Time Locked
Contract); or vice versa, having an HTLC-based onchain payment first to pay into
a Lightning channel. But isn’t paying out of a channel balance to an external
address just a splice? Sorry, I’m the terminology nerd here! I think they just
implemented splicing even if they call it submarine swaps.</p>
<p><strong>Mike Schmidt:</strong> Yeah, they’re calling it Submarine Payments actually in their
release notes, and then they also refer to it as, “Supporting reverse swaps to
external address”. But yes, functionally similar to what you outlined there.</p>
<p><strong>Mark Erhardt:</strong> Sounds like a splice to me, outgoing splice. Anyway. Let’s
move on.</p>
<p><strong>Mike Schmidt:</strong> We’ll jump to Releases and release candidates and also Notable
code and documentation changes. Gustavo authors this every week, which we are
very grateful for. So, he is the most informed person on this podcast to also
walk us through it. And we’re grateful for that as well. Gustavo, what do we
have this week?</p>
<p id="btcpay-server-2-3-5-transcript"><em>BTCPay Server 2.3.5</em></p>
<p><strong>Gustavo Flores Echaiz:</strong> Thank you, Mike and Murch for the intro. Yeah, so on
the releases, we have one from BTCPay Server and one from LND. Both are pretty
straight forward and pretty light. So, the BTCPay Server v2.3.5 mostly adds
support for multi-coin support, so BTCPay Server allows you to use bitcoin, but
other altcoins as well. So, support is extended that, for example, you don’t
need to use bitcoin if you’re using other UTXO-model coins. Previously, you
were forced to sync a Bitcoin node to use other coins that are also based on the
UTXO model; now, you’re no longer forced to sync a Bitcoin node for that. Just
other things that were added are additional fixes, some user-visible fixes, such
as an image that wouldn’t display correctly on mobile. And an important one is
payments were getting undetected on LND, when your LND node restarted while your
BTCPay Server store was listening for LND for a new payment. Then, on a
restart, it would fail to listen to new payments. So, that bug fix was also
part of this release.</p>
<p>Finally, some new currency exchange rate providers for some additional
currencies, I believe, mostly INR, which is probably Indonesia or India based.</p>
<p id="lnd-0-20-1-beta-transcript"><em>LND 0.20.1-beta</em></p>
<p>And then the next release is LND v0.20.1. So, we teased, I believe, in two,
three newsletters ago, the RC of this release, and now this is the official
release. There’s many bug fixes included here. One that I highlighted was a
panic recovery from gossip message processing, improvement around reorg
protection, and LSP detection heuristics. So, these are things we’ve talked
about in previous podcast episodes. But there’s about ten bug fixes included in
this. And the heaviest part of the release are the bug fixes and the additional
features that I mentioned earlier. That would be it for this part, unless you
guys have any notes. No? Awesome.</p>
<p id="bitcoin-core-33965-transcript"><em>Bitcoin Core #33965</em></p>
<p>So, we can proceed with the notable code and documentation changes. So, we have
one from Bitcoin Core and a few ones from the LN implementations; and finally, a
new BIP, BIP360, and two updates on the BOLT specification. So, let’s start
with the Bitcoin Core PR #33965. So, here, a bug is fixed around a concept
called -blockreservedweight. So, when a miner constructs a block, he will
reserve some weight of the block for the block header and the coinbase
transaction. That is what this value sets. So, there’s two ways of setting
this value. Most RPC clients will simply set it to the startup config,
-blockreservedweight. However, if you’re an IPC caller, particularly a Stratum
v2 external client, you will use the mining interface and you will create your
own block using another value set, also called block_reserved_weight.</p>
<p>The problem was that if I’m an IPC client and I’m using the second value
block_reserved_weight, and I also set a startup config -blockreservedweight,
they will enter in conflict, and the startup config option will overwrite
silently the other value set. So, here, what is done is that if an IPC caller
sets specifically the IPC value, then the startup config value that would
previously override it is now ignored for the one that IPC callers specify for
that one to take effect. Yes, Murch?</p>
<p><strong>Mark Erhardt:</strong> Basically, this is just more special case overrides more
general case. And so, the general case is the startup configuration. The node
generally uses the startup config. But if you specify something more specific,
per the IPC, that should take precedence. And the bug here was that the startup
configuration took precedence rather than the mining IPC value. So, both of
them can set it, and if a client specifies something specifically on the call
that it is making, then obviously that’s more important.</p>
<p><strong>Gustavo Flores Echaiz:</strong> That’s exactly right, Murch. Thank you for
clarifying that. So, that is fixed. Another part of this PR is also the
enforcement of a value called MINIMUM_BLOCK_RESERVED_WEIGHT that would silently
clamp a value that was conflicting with this minimum value. And now, instead of
silently failing, it will respond with an error message telling you that you
cannot set a block reserve weight value that conflicts with the
MINIMUM_BLOCK_RESERVED_WEIGHT setting.</p>
<p id="eclair-3248-transcript"><em>Eclair #3248</em></p>
<p>So, we move forward with Eclair. We have #3248, which is a fairly simple PR,
where basically if you have the option as a note to forward a payment through a
private channel or a public channel to the same destination, now Eclair will
prioritize the private channels when relaying payments, simply because private
channels are not publicly viewable. So, if you’re taking a public channel,
you’re then sending a channel update to the rest of the network, and the network
believes you have less capacity because they’re unable to see that you also have
a private channel with similar capacity. So, Eclair now always prioritizes the
private channel. But there’s another part of this PR that when two channels
have the same visibility, let’s say I have two private channels or two public
channels, Eclair now prioritizes the channel with the smaller balance. This
allows it to keep channels with bigger balances available for payments that
would need more capacity. Any comments here? Perfect.</p>
<p id="eclair-3246-transcript"><em>Eclair #3246</em></p>
<p>We move forward with Eclair #3246. So, here, many new fields are added to
internal events. For example, miningFee field present in an internal event
called TransactionPublished is split between localMiningFee and remoteMiningFee.
Another computed feerate field is also added to this event. The point here,
maybe the details are not as important as to understand why this was done. The
goal here is to bring more visibility or auditability into the economic
performance of our peers as a node. So, if we’re able to get all details around
the fees paid at all levels then we have better visibility into the economic
feasibility or economic performance of our different peers. Another important
point is an optional purchase liquidity ads field is added to link a transaction
to a liquidity purchase. So, if you made a transaction through a liquidity
purchase, now a field appears that would link the transaction with that
liquidity purchase.</p>
<p>Also, channel lifecycle events now include a field called commitmentFormat to
describe the channel type, whether this was an anchor or non-anchor channel
type, and eventually other forms of channel types, such as simple taproot
channels. So, yeah, all of these fields, the goal is to bring more visibility
into the economic performance of your different peers.</p>
<p id="ldk-4335-transcript"><em>LDK #4335</em></p>
<p>We move forward with two PRs around LDK. The first one, #4335, this is an
interesting one. It brings a concept back that was mentioned in Newsletter
#188, called phantom node payments. And it applies it for BOLT12 offers. So,
what is a phantom node payment? It’s a payment that multiple nodes can claim.
In the BOLT11 format, it uses something similar to stateless invoices.
Basically, it points to a phantom node, a node that doesn’t exist, but multiple
nodes could basically intercept that payment and keep it. Yes, Murch?</p>
<p><strong>Mark Erhardt:</strong> Right, basically the idea is if you run a large operation on
the LN, you might have multiple nodes running at the same time that are
load-balancing, and they have their own channels, and you want to be able to
spin out one of them and do an update, or whatever, while still being able to
process all of the payments. And in order to do so, you create a pretend node
or make up a node that sits as a channel partner behind all of your other nodes.
So, let’s say you have three nodes, Alice, Bob and Charlie. They are the actual
Lightning nodes that have actual channels to other nodes in the network. And
then, you make up a phantom node, Philip, that has a virtual pretend connection,
like super-big channel, between Alice and Philip, Bob and Philip and Carol and
Philip. And now, every time you get a payment, you make out all of your
invoices to Philip, but they could all go through any of the three other nodes
to reach Philip. And instead, you collect the payment at the level of Alice,
Bob and Carol.</p>
<p><strong>Mike Schmidt:</strong> I’ve been thinking about it. You guys tell me if I’m thinking
about it the right way. Is this sort of like load-balancing, like everything
goes through one, but then it can get routed to one of three behind the scenes?
Is that kind of how it works?</p>
<p><strong>Mark Erhardt:</strong> No, it always goes to one. And by trying to go to that one,
it will have to pass through one of the three. And similar, but not quite the
same. And by having these other three nodes that all do their own channels,
that all have liquidity floating around, if for example one of the three nodes
had all of their capacity on the outbound side and couldn’t receive an inbound
payment, if you can’t route through Alice to Philip, you can route through Bob
to Philip. Or if Carol is getting a software update and is down for three
minutes, you can still route for Alice and Bob. But all of the invoices are
created as if Philip were the recipient, and that way you get that flexibility
for routing from any of your nodes. Otherwise, if you gave out all of the
invoices with Alice, Bob or Carol, if one of them goes down, that node can’t
receive, or if the liquidity locks up. I mean, you could still have huge-ass
channels between Alice, Bob and Carol in order to make that work most of the
time. But if one of them is actually offline, you just can’t receive those
payments at that time and all of the payments will fail. So, it’s sort of a
trick to be able to get redundancy.</p>
<p><strong>Gustavo Flores Echaiz:</strong> So, in this PR, basically this feature is brought for
BOLT12 offers. So, as a receiver, I will create a BOLT12 offer with multiple
blinded paths, and let’s say I have three different blinded paths and each one
would terminate at a different node that I have, right? So, then, technically
the payment could be made to any of those nodes once they received any of those
nodes’ response to the invoice request, but the resulting invoice after the
invoice request can only be paid to the responding node. So, let’s say the
phantom payment part only happens at the invoice request level, and then it can
only, once there’s an invoice issued, that invoice can only be paid to one
specific node.</p>
<p><strong>Mark Erhardt:</strong> I just realized something completely unrelated, but if you
have a blinded path and the payment fails in the blinded section of that path,
you do know what nodes were in that. Do you learn what nodes were in the
blinded path by them reporting the issue? We should have a Lightning person on
this.</p>
<p><strong>Mike Schmidt:</strong> This is when the t-bast bat signal, the bast signal should go
up.</p>
<p><strong>Mark Erhardt:</strong> The bast signal, wow! Yeah, the t-bast signal. Anyway, if you
know the answer, you could just enlighten us on Twitter below this post or
something.</p>
<p><strong>Gustavo Flores Echaiz:</strong> Maybe through some sort of attributable failures
implementation, this could be known, you know, but maybe there’s even
limitations to that.</p>
<p id="ldk-4318-transcript"><em>LDK #4318</em></p>
<p>So, we move forward with LDK #4318. This is a fairly simple one where the
max_funding_satoshis field from the ChannelHandshakeLimits is removed. And what
does that mean? It basically removes the pre-wumbo or the pre-large channels
default channel size limit. So, there was an issue because LDK, at the same
time, by default was limiting channels to the pre-wumbo default channel size
limit, but at the same time it was advertising support for large channels by
default. So, if you were a peer of an LDK node, you might try to open a large
channel to an LDK node for them to see that it fails, because LDK advertised
support for large channels, but behind the scenes it didn’t really accept them.
So, now, this PR basically brings the advertising to be real. Now, LDK by
default will accept large channels. Users, however, who want to limit risk and
want to avoid large channels can use the manual channel acceptance flow and can
configure rejecting channels that are of a larger size than they want.</p>
<p id="lnd-10542-transcript"><em>LND #10542</em></p>
<p>We move forward of LND #10542. So, this is an interesting one because the graph
database layer is basically extended to add support for gossip v1.75, also
called gossip v2. This was mentioned in Newsletter #261 and #326, but basically
gossip v1.75 is an extension of the gossip protocol to allow for channel
announcements of simple taproot channels. So, we know LND has been going down
the simple taproot channel direction for a while and this has been work building
for a long time. So, now LND can store and retrieve channel announcements on
its database. However, this doesn’t mean that LND has completed support for
gossip v1.75. It remains disabled at the network level, pending completion of
validation and gossiper subsystems. So, additional work is required for LND’s
implementation of gossip v1.75 to take fully effect.</p>
<p id="bips-1670-transcript"><em>BIPs #1670</em></p>
<p>We move forward with BIPs #1670. This is the publication, or it adds basically
BIP360, which specifies Pay-to-Merkle-Root or P2MR, which is a new output type
that is very similar to P2TR, the taproot output type, but it removes its
keypath spending or keyspending path. The reason why this is done, it’s to be
resistant to long exposure attacks by cryptographically relevant quantum
computers. So, this is a topic that has been discussed a lot publicly, how to
make for taproot or P2TR output types to be resistant to, let’s say, a quantum
computer using the Shor’s algorithm. Well, this is the solution for that.
However, this is not a new output type that would protect against short-exposure
attacks, because when you broadcast your transaction of a P2MR output, you would
then sign for that output. And during the time it is unconfirmed, there could
be a short-exposure attack theoretically from a quantum computer. So,
additional research is being done for other post-quantum signature proposals.
I’m guessing, Murch, you might have some comments on this?</p>
<p><strong>Mark Erhardt:</strong> Yeah, so BIP360 had been in the works for, I think, over two
years. The proposal was previously named differently, too. So, if you don’t
recognize P2MR, you might have known it as pay to tapscript hash (P2TSH) or pay
to quantum resistant hash (P2QRH) before. It really came together in the past
couple of months after it got a complete rewrite. And basically, it is the
first concrete proposal for any output type that has any benefit regarding
quantum. My understanding is that the authors are looking into combining this
with an actual post-quantum secure signature scheme, which we’ve heard a lot
about here as well from, for example, Jonas Nick and Mikhail, that were on in
the last month or so. Anyway, as Gustavo said, P2MR uses the same tapscript
stuff under the hood, just like P2TSH, but because it doesn’t reveal an ECDSA
public key onchain, it is not vulnerable to long-exposure attacks. It is still
vulnerable to long-exposure attacks if an address is reused, and the
post-quantum signature scheme is not available yet. So, the idea would be,
presumably, to put a post-quantum signature scheme into an OP_SUCCESS opcode,
and then use that directly in tapscript, which is the script variant that we use
in P2TR leaf scripts, and then also now in P2MR leaf scripts.</p>
<p>Yeah, the obvious downside of these post-quantum schemes is that all of the so
far proposed ones are much, much larger, with public keys being about 3,000
bytes and signatures being somewhere around 8,000 bytes. And if we compare that
to the current 32-byte public keys and 64-byte transactions, that’s a two
magnitude increase, of course. And, yeah, so we’ll keep monitoring this
situation. So far, I’ve not been affronted by any quantum computer on my way to
work, but we’ll keep working on this, I guess.</p>
<p><strong>Mike Schmidt:</strong> Murch, you mentioned this is a step towards quantum
resistance, but in terms of just having P2MR, you mentioned the short range, so
I mean, P2SH, for example, would be equally as safe, right, these sorts of
things?</p>
<p><strong>Mark Erhardt:</strong> That is correct, yes. So, P2WPKH or P2SH would give you the
same resistance to quantum attackers right now, as long as you don’t reuse any
addresses where you reveal the actual spending conditions only at spending time.
And then, the attacker would have to reverse the private key from the public key
in the time from the unconfirmed transaction being broadcast and confirmed in
the chain. So, given that quantum computers are actually pretty slow, or
there’s different variants, but basically just the calculations take on the
order of hours. If you make a transaction that goes into a block i n the next
hour, you’re just not going to be vulnerable to that, and also not going to be
vulnerable to that if we ever get quantum computers that can make calculations
that can calculate private keys.</p>
<p>So, far, my understanding is that there are projects that have come up with one
physical qubit, and it’s a big question how to get two of them to talk to each
other. There are also advances on algorithms for quantum attacks, and the
number of qubits that are necessary to make these attacks keeps going down. But
if we’re actually still at a phase where these computers can run only in huge
facilities that are physically cool to almost absolute zero, where you have to
shoot lasers at specific spots on the chips in order to introduce the quantum
state, then you have tons of noise reading that out. And we have no clue how to
make two of them talk to each other with, as far as I’m aware, the only
experiments that have been successful being factoring 15 and 21, when the
circuit design already included those numbers as heavily hinted, in order to
even factor numbers like that. I’m just not very scared that we’re going to be
able to factor 256-bit numbers anytime soon, and especially not in the time
between an unconfirmed transaction being broadcast and an unconfirmed
transaction being confirmed. So, yeah, I’m still very much in the camp that we
have to react to quantum because so many people are worried about quantum, but
I’m not worried about quantum computers.</p>
<p><strong>Mike Schmidt:</strong> Well, it seems like maybe the Bitcoin community should be
worried about quantum in proportion to the output of the quantum side of the
equation, right? It’s like you said, Murch, it can’t factor 21, but Bitcoin’s
supposed to have a signature scheme deployed, right?</p>
<p><strong>Mark Erhardt:</strong> I mean, other systems are upgrading right now. So, NIST has
been recommending that all online systems, websites, and online banking, and so
forth use post-quantum cryptography by, I think, 2035 or 2030. And of course,
for these systems, that’s fairly easy because when we’re streaming hundreds of
GB of data just to watch movies, well, GB per hour per user, then sending a few
kB to establish an encrypted connection is not a big deal. But in Bitcoin, what
we’re doing is we have a highly replicated, very, very small throughput
blockchain, and if we have 1 MB or up to 4 MB per 10 minutes, giving them away
in chunks of 3,000 to 8,000 bytes for public keys and signatures is going to
significantly reduce the throughput. And therefore, for us, the trade-off means
that we’re going to reduce our capacity by 100x if we just blindly roll this out
today. And meanwhile, with all of the recent interest in the topic again,
cryptography is making progress. So, if we wait a couple of years, we might
have way more efficient schemes, way smaller schemes, that we’d much rather
commit to maintaining for the next five decades, hundred years, whatever.</p>
<p>So, I think being aware, doing the research, putting it into the context of the
trade-offs that we are solving for in Bitcoin is currently the right strategy.
And saying that we need post-quantum signature schemes yesterday in Bitcoin, and
everybody should also start using them right now, is I think just a little too
rushed.</p>
<p><strong>Mike Schmidt:</strong> Agreed.</p>
<p><strong>Gustavo Flores Echaiz:</strong> Thank you Murch, I completely agree with all you
said. So, listeners can look up the episodes in Newsletter #344 for the first
coverage that we did on this BIP360, when it was called P2QRH, and Newsletter
#385, which was a Year-End Newsletter, also has a strong, big section around
quantum which includes this when it was called P2TSH.</p>
<p id="bolts-1236-transcript"><em>BOLTs #1236</em></p>
<p>We move forward with BOLTs #1236. Here, the specification around dual-funding
channels is updated to allow either node to send RBF to basically fee bump a
channel funding transaction. However, previously, only the channel initiator
could do this and now this is extended for both peers to be able to do it. The
reason why this is done is because in the PR #1160 that defines channel
splicing, this is a proposed part of splicing. So, the goal was to align dual
funding with splicing to allow both sides to initiate an RBF. There’s also
requirements added that both senders of the RBF initiation must reuse at least
one input from a previous attempt, ensuring that the new transaction
double-spends prior attempts, right? So, this is a condition around RBF, but
it’s more properly specified in this PR to make sure that all details are
covered. Any thoughts here?</p>
<p id="bolts-1289-transcript"><em>BOLTs #1289</em></p>
<p>Finally, BOLTs #1289 changes how the commitment_signed message is retransmitted
when nodes reconnect in the interactive transaction protocol, which applies both
to dual funding and splicing. So, the reason why the work here is done is
because the goal is to avoid unnecessary retransmission, which is especially
important for simple taproot channels, when retransmitting the commitment_signed
message would require a full MuSig2 signing round due to nonce changes. In
other channel types, this is not that concerning. You could just simply
retransmit the commitment_signed message. But because we’re now considering for
simple taproot channels, we’ve got to consider the work done every time you
retransmit the message. So, like I said previously, commitment_signed was
always retransmitted when nodes would reconnect, even if the peer had already
received it.</p>
<p>So now, instead, the message channel_reestablish includes an explicit field that
basically lets a node request for the commitment_signed message if it still
needs it. So, in most cases, a node that would come back online would simply
tell the other node, “Hey, by the way, I got your commitment_signed message
before I shut down, before I restarted, so you don’t have to send it again”.
So, this allows for a more seamless flow, specifically when it comes to simple
taproot channels. And that’s the last PR of this newsletter and that completes
the whole newsletter as well.</p>
<p><strong>Mike Schmidt:</strong> Thanks Gustavo, great job. We want to also thank our guests
today, arbedout, Erik, and Misha, who joined us earlier for their segments. And
I also want to thank Murch for co-hosting and you all for listening. We’ll hear
you next week. Cheers.</p>Bitcoin OptechMark “Murch” Erhardt, Gustavo Flores Echaiz, and Mike Schmidt are joined by Misha Komarov, Erik De Smedt, and arbedout to discuss Newsletter #393.Bitcoin Optech Newsletter #3932026-02-20T00:00:00+00:002026-02-20T00:00:00+00:00https://bitcoinops.org/en/newsletters/2026/02/2026-02-20-newsletter<p>This week’s newsletter summarizes a discussion about recent OP_RETURN usage and
describes a protocol to enforce covenant-like spending conditions without
consensus changes. Also included are our regular sections describing recent
changes to services and client software, announcing new releases and release
candidates, and summarizing recent merges to popular Bitcoin infrastructure
software.</p>
<h2 id="news">News</h2>
<ul>
<li id="recent-op-return-output-statistics" class="anchor-list">
<p><a href="#recent-op-return-output-statistics" class="anchor-list-link">●</a> <strong>Recent OP_RETURN output statistics</strong>: Anthony Towns posted to
<a href="https://delvingbitcoin.org/t/recent-op-return-output-statistics/2248">Delving</a> about the recent OP_RETURN statistics since
the release of Bitcoin Core v30.0 on October 10, which included changes to
the mempool policy limits for OP_RETURN outputs (allowing multiple OP_RETURN
outputs and allowing up to 100kB of data in OP_RETURN outputs). The range of
blocks he looked at was heights 915800 to 936000, with the following
results:</p>
<ul>
<li>
<p>24,362,310 txs with OP_RETURN outputs</p>
</li>
<li>
<p>61 txs with multiple OP_RETURN outputs</p>
</li>
<li>
<p>396 txs with total OP_RETURN output script sizes greater than 83 bytes</p>
</li>
<li>
<p>Total OP_RETURN output script data over the period was 473,815,552 bytes (of
which large OP_RETURNS accounted for 0.44%)</p>
</li>
<li>
<p>There are 34,283 txs burning sats to OP_RETURN outputs, for a total of
1,463,488 sats burnt</p>
</li>
<li>
<p>There are 949,003 txs with between 43 and 83 bytes of OP_RETURN data, and
23,412,911 txs with OP_RETURN data of 42 bytes or less</p>
</li>
</ul>
<p>Towns also included a chart showing the frequency of sizes for the 396
transactions with large OP_RETURN outputs. 50% of these transactions had less
than 210 bytes of OP_RETURN data. Also, 10% had more than 10KB of OP_RETURN
data.</p>
<p>He later added that Murch subsequently published a <a href="https://x.com/murchandamus/status/2022930707820269670">similar analysis</a> on
X and a <a href="https://dune.com/murchandamus/opreturn-counts">dashboard</a> of OP_RETURN
statistics, and that orangesurf published a <a href="https://research.mempool.space/opreturn-report/">report</a> on
OP_RETURN for mempool research. <a href="/en/podcast/2026/02/24/#recent-op-return-output-statistics"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-pipes-v2" class="anchor-list">
<p><a href="#bitcoin-pipes-v2" class="anchor-list-link">●</a> <strong>Bitcoin PIPEs v2</strong>: Misha Komarov <a href="https://delvingbitcoin.org/t/bitcoin-pipes-v2/2249">posted</a> to Delving Bitcoin
about Bitcoin PIPEs, a protocol that allows enforcement of spending conditions
without the need for consensus changes or optimistic challenge mechanisms.</p>
<p>The Bitcoin protocol is based on a minimal transaction validation model, which
consists of verifying that a UTXO being spent is authorized by a valid digital
signature. Thus, instead of relying on spending conditions expressed by Bitcoin
Script, Bitcoin PIPEs adds prerequisites on whether a valid signature can be
produced or not. In other words, a private key is cryptographically locked behind a
predetermined condition. If and only if the condition is fulfilled, the private key
is revealed, allowing for a valid signature. While the Bitcoin protocol
only has to validate a single <a href="/en/topics/schnorr-signatures/">schnorr signature</a>,
all the conditional logic is processed off-chain.</p>
<p>On a formal level, Bitcoin PIPEs consists of two main phases:</p>
<ul>
<li id="setup" class="anchor-list">
<p><a href="#setup" class="anchor-list-link">●</a> <em>Setup</em>: A standard Bitcoin keypair <code class="language-plaintext highlighter-rouge">(sk, pk)</code> is generated. <code class="language-plaintext highlighter-rouge">sk</code> is then
encrypted behind a spending condition statement using witness encryption.</p>
</li>
<li id="signing" class="anchor-list">
<p><a href="#signing" class="anchor-list-link">●</a> <em>Signing</em>: A witness <code class="language-plaintext highlighter-rouge">w</code> is provided for the statement. If <code class="language-plaintext highlighter-rouge">w</code> is valid, <code class="language-plaintext highlighter-rouge">sk</code> is
revealed and a schnorr signature can be produced. Otherwise, recovering <code class="language-plaintext highlighter-rouge">sk</code>
becomes computationally infeasible.</p>
</li>
</ul>
<p>According to Komarov, Bitcoin PIPEs can be used to reproduce <a href="/en/topics/covenants/">covenant</a> semantics. In
particular, <a href="https://eprint.iacr.org/2026/186">Bitcoin PIPEs v2</a> focuses on a limited set of spending
conditions, enforcing binary covenants. This model naturally captures a wide range of
useful conditions whose outcomes are binary, such as providing a valid zk-proof,
satisfying an exit condition, or existence of a fraud proof. Basically, it all comes
down to a single question: “Is the condition satisfied or not?”.</p>
<p>Finally, Komarov provided real-world examples of how PIPEs could be leveraged instead
of new opcodes, and how it could be used to improve the optimistic verification flow
of the <a href="/en/topics/acc/">BitVM</a> protocol. <a href="/en/podcast/2026/02/24/#bitcoin-pipes-v2"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="changes-to-services-and-client-software">Changes to services and client software</h2>
<p><em>In this monthly feature, we highlight interesting updates to Bitcoin
wallets and services.</em></p>
<ul>
<li id="second-releases-hark-based-ark-software" class="anchor-list">
<p><a href="#second-releases-hark-based-ark-software" class="anchor-list-link">●</a> <strong>Second releases hArk-based Ark software:</strong>
Second’s <a href="/en/topics/ark/">Ark</a> libraries were updated to use hArk, hash-lock Ark,
in version <a href="https://docs.second.tech/changelog/changelog/#010-beta6">0.1.0-beta.6</a>. The new protocol eliminates the
synchronous interactivity requirement for users during rounds, with its own
set of tradeoffs. The release includes various other updates,
including breaking changes. <a href="/en/podcast/2026/02/24/#second-releases-hark-based-ark-software"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="amboss-announces-railsx" class="anchor-list">
<p><a href="#amboss-announces-railsx" class="anchor-list-link">●</a> <strong>Amboss announces RailsX:</strong>
The <a href="https://amboss.tech/blog/railsx-first-lightning-native-dex">RailsX announcement</a> outlines a platform using LN and
<a href="/en/topics/client-side-validation/">Taproot Assets</a> to support swaps and various
other financial services. <a href="/en/podcast/2026/02/24/#amboss-announces-railsx"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="nunchuk-adds-silent-payment-support" class="anchor-list">
<p><a href="#nunchuk-adds-silent-payment-support" class="anchor-list-link">●</a> <strong>Nunchuk adds silent payment support:</strong>
Nunchuk <a href="https://x.com/nunchuk_io/status/2021588854969414119">announced</a> support for sending to <a href="/en/topics/silent-payments/">silent
payment</a> addresses. <a href="/en/podcast/2026/02/24/#nunchuk-adds-silent-payment-support"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="electrum-adds-submarine-swap-features" class="anchor-list">
<p><a href="#electrum-adds-submarine-swap-features" class="anchor-list-link">●</a> <strong>Electrum adds submarine swap features:</strong>
<a href="https://github.com/spesmilo/electrum/blob/master/RELEASE-NOTES">Electrum 4.7.0</a> allows users to pay onchain using
their Lightning balance (see <a href="/en/topics/submarine-swaps/">submarine swaps</a>), among
other features and fixes. <a href="/en/podcast/2026/02/24/#electrum-adds-submarine-swap-features"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="sigbash-v2-announced" class="anchor-list">
<p><a href="#sigbash-v2-announced" class="anchor-list-link">●</a> <strong>Sigbash v2 announced:</strong>
<a href="https://x.com/arbedout/status/2020885323778044259">Sigbash v2</a> now uses <a href="/en/topics/musig/">MuSig2</a>, WebAssembly
(WASM), and zero-knowledge proofs to achieve better cosigning-service privacy.
See our <a href="/en/newsletters/2024/04/17/#key-agent-sigbash-launches">previous coverage</a> on Sigbash for more. <a href="/en/podcast/2026/02/24/#sigbash-v2-announced"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="releases-and-release-candidates">Releases and release candidates</h2>
<p><em>New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.</em></p>
<ul>
<li id="btcpay-server-2-3-5" class="anchor-list">
<p><a href="#btcpay-server-2-3-5" class="anchor-list-link">●</a> <a href="https://github.com/btcpayserver/btcpayserver/releases/tag/v2.3.5">BTCPay Server 2.3.5</a> is a minor release of this self-hosted payment
solution that adds multi-crypto wallet balance widgets on the dashboard,
a custom textbox for checkout, new exchange rate providers, and includes
several bug fixes. <a href="/en/podcast/2026/02/24/#btcpay-server-2-3-5"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="lnd-0-20-1-beta" class="anchor-list">
<p><a href="#lnd-0-20-1-beta" class="anchor-list-link">●</a> <a href="https://github.com/lightningnetwork/lnd/releases/tag/v0.20.1-beta">LND 0.20.1-beta</a> is a maintenance release of this popular LN node
implementation, which adds a panic recovery for gossip message
processing, improves reorg protection, implements LSP detection
heuristics, and fixes multiple bugs and race conditions. <a href="/en/podcast/2026/02/24/#lnd-0-20-1-beta"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes">Notable code and documentation changes</h2>
<p><em>Notable recent changes in <a href="https://github.com/bitcoin/bitcoin">Bitcoin Core</a>, <a href="https://github.com/ElementsProject/lightning">Core
Lightning</a>, <a href="https://github.com/ACINQ/eclair">Eclair</a>, <a href="https://github.com/lightningdevkit/rust-lightning">LDK</a>,
<a href="https://github.com/lightningnetwork/lnd/">LND</a>, <a href="https://github.com/bitcoin-core/secp256k1">libsecp256k1</a>, <a href="https://github.com/bitcoin-core/HWI">Hardware Wallet
Interface (HWI)</a>, <a href="https://github.com/rust-bitcoin/rust-bitcoin">Rust Bitcoin</a>, <a href="https://github.com/btcpayserver/btcpayserver/">BTCPay
Server</a>, <a href="https://github.com/bitcoindevkit/bdk">BDK</a>, <a href="https://github.com/bitcoin/bips/">Bitcoin Improvement
Proposals (BIPs)</a>, <a href="https://github.com/lightning/bolts">Lightning BOLTs</a>,
<a href="https://github.com/lightning/blips">Lightning BLIPs</a>, <a href="https://github.com/bitcoin-inquisition/bitcoin">Bitcoin Inquisition</a>, and <a href="https://github.com/bitcoin-inquisition/binana">BINANAs</a>.</em></p>
<ul>
<li id="bitcoin-core-33965" class="anchor-list">
<p><a href="#bitcoin-core-33965" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/33965">Bitcoin Core #33965</a> fixes a bug where the <code class="language-plaintext highlighter-rouge">-blockreservedweight</code>
startup config (see <a href="/en/newsletters/2025/02/21/#bitcoin-core-31384">Newsletter #342</a>) could silently
override the <code class="language-plaintext highlighter-rouge">block_reserved_weight</code> value set by Mining IPC clients
(see <a href="/en/newsletters/2024/07/05/#bitcoin-core-30200">Newsletter #310</a>). Now, when an IPC caller sets
the latter, it takes precedence. For RPC callers who never set this
value, the startup config <code class="language-plaintext highlighter-rouge">-blockreservedweight</code> always takes effect.
This PR also enforces the <code class="language-plaintext highlighter-rouge">MINIMUM_BLOCK_RESERVED_WEIGHT</code> for IPC
callers, preventing them from setting a value below it. <a href="/en/podcast/2026/02/24/#bitcoin-core-33965"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="eclair-3248" class="anchor-list">
<p><a href="#eclair-3248" class="anchor-list-link">●</a> <a href="https://github.com/ACINQ/eclair/issues/3248">Eclair #3248</a> starts prioritizing private channels over public ones
when forwarding <a href="/en/topics/htlc/">HTLCs</a>, if both options are available.
This keeps more liquidity available in public channels, which are
visible to the network. When two channels have the same visibility,
Eclair now prioritizes the channel with the smaller balance. <a href="/en/podcast/2026/02/24/#eclair-3248"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="eclair-3246" class="anchor-list">
<p><a href="#eclair-3246" class="anchor-list-link">●</a> <a href="https://github.com/ACINQ/eclair/issues/3246">Eclair #3246</a> adds new fields to several internal events:
<code class="language-plaintext highlighter-rouge">TransactionPublished</code> splits the single <code class="language-plaintext highlighter-rouge">miningFee</code> field into
<code class="language-plaintext highlighter-rouge">localMiningFee</code> and <code class="language-plaintext highlighter-rouge">remoteMiningFee</code>, adds a computed <code class="language-plaintext highlighter-rouge">feerate</code> and
an optional <code class="language-plaintext highlighter-rouge">LiquidityAds.PurchaseBasicInfo</code> linking the transaction
to a <a href="/en/topics/liquidity-advertisements/">liquidity purchase</a>. Channel
lifecycle events now include the <code class="language-plaintext highlighter-rouge">commitmentFormat</code> to describe the
channel type, and <code class="language-plaintext highlighter-rouge">PaymentRelayed</code> adds a <code class="language-plaintext highlighter-rouge">relayFee</code> field. <a href="/en/podcast/2026/02/24/#eclair-3246"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4335" class="anchor-list">
<p><a href="#ldk-4335" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4335">LDK #4335</a> adds initial support for phantom node payments (see
<a href="/en/newsletters/2022/02/23/#ldk-1199">Newsletter #188</a>) using <a href="/en/topics/offers/">BOLT12 offers</a>. In the <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md">BOLT11</a> version, invoices included route hints
pointing to a non-existent “phantom” node, with each path’s last hop
being a real node that could accept the payment using <a href="/en/topics/stateless-invoices/">stateless
invoices</a>. In <a href="https://github.com/lightning/bolts/blob/master/12-offer-encoding.md">BOLT12</a>, the offer simply
includes multiple <a href="/en/topics/rendez-vous-routing/">blinded paths</a> terminating at each
participating node. The current implementation allows multiple nodes to
respond to the invoice request, though the resulting invoice can only
be paid to the responding node. <a href="/en/podcast/2026/02/24/#ldk-4335"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4318" class="anchor-list">
<p><a href="#ldk-4318" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4318">LDK #4318</a> removes the <code class="language-plaintext highlighter-rouge">max_funding_satoshis</code> field from the
<code class="language-plaintext highlighter-rouge">ChannelHandshakeLimits</code> struct, effectively eliminating the
pre-<a href="/en/topics/large-channels/">wumbo</a> default channel size limit. LDK was
already advertising support for <a href="/en/topics/large-channels/">large channels</a>
via the <code class="language-plaintext highlighter-rouge">option_support_large_channels</code> feature flag by default, which
could have incorrectly signaled support to peers by conflicting with
the former setting. Users who want to limit risk can use the manual
channel acceptance flow. <a href="/en/podcast/2026/02/24/#ldk-4318"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="lnd-10542" class="anchor-list">
<p><a href="#lnd-10542" class="anchor-list-link">●</a> <a href="https://github.com/lightningnetwork/lnd/issues/10542">LND #10542</a> extends the graph database layer to support gossip v1.75
(see Newsletters <a href="/en/newsletters/2023/07/26/#updated-channel-announcements">#261</a> and <a href="/en/newsletters/2024/10/25/#updates-to-the-version-1-75-channel-announcements-proposal">#326</a>).
LND can now store and retrieve <a href="/en/topics/channel-announcements/">channel announcements</a> for <a href="/en/topics/simple-taproot-channels/">simple taproot channels</a>. Gossip v1.75 remains disabled at the network level, pending
the completion of the validation and gossiper subsystems. <a href="/en/podcast/2026/02/24/#lnd-10542"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-1670" class="anchor-list">
<p><a href="#bips-1670" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/1670">BIPs #1670</a> publishes <a href="https://github.com/bitcoin/bips/pull/1670">BIP360</a>, which specifies Pay-to-Merkle-Root
(P2MR), a new output type that operates like <a href="/en/topics/taproot/">P2TR</a> but
with the keypath spend removed. P2MR outputs are resistant to
long-exposure attacks by cryptographically relevant quantum computers
(CRQCs) because they commit directly to the Merkle root of the script tree, a SHA256 hash, rather
than a public key. However, protection against
short-exposure attacks, such as against private key recovery while a
transaction is unconfirmed, requires a separate <a href="/en/topics/quantum-resistance/">post-quantum</a> signature
proposal. See <a href="/en/newsletters/2025/03/07/#update-on-bip360-pay-to-quantum-resistant-hash-p2qrh">Newsletter #344</a> for earlier coverage when the
proposal was known as P2QRH and <a href="/en/newsletters/2025/12/19/#quantum">Newsletter #385</a> when the proposal was
known as P2TSH. <a href="/en/podcast/2026/02/24/#bips-1670"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bolts-1236" class="anchor-list">
<p><a href="#bolts-1236" class="anchor-list-link">●</a> <a href="https://github.com/lightning/bolts/issues/1236">BOLTs #1236</a> updates the <a href="/en/topics/dual-funding/">dual funding</a>
specification to allow either node to send <code class="language-plaintext highlighter-rouge">tx_init_rbf</code> during
channel establishment, effectively allowing both parties to <a href="/en/topics/replace-by-fee/">fee
bump</a> the funding transaction. Previously, only the channel
initiator could do so. This change aligns dual funding with <a href="/en/topics/splicing/">splicing</a>, where either side could already initiate an RBF. The PR
also adds a requirement that both the senders of <code class="language-plaintext highlighter-rouge">tx_init_rbf</code> and
<code class="language-plaintext highlighter-rouge">tx_ack_rbf</code> must reuse at least one input from a previous attempt,
ensuring that the new transaction double-spends all prior attempts. <a href="/en/podcast/2026/02/24/#bolts-1236"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bolts-1289" class="anchor-list">
<p><a href="#bolts-1289" class="anchor-list-link">●</a> <a href="https://github.com/lightning/bolts/issues/1289">BOLTs #1289</a> changes how <code class="language-plaintext highlighter-rouge">commitment_signed</code> is retransmitted
during reconnection in the interactive transaction protocol used by
both <a href="/en/topics/dual-funding/">dual funding</a> and <a href="/en/topics/splicing/">splicing</a>.
Previously, <code class="language-plaintext highlighter-rouge">commitment_signed</code> was always retransmitted on
reconnection, even if the peer had already received it. Now,
<code class="language-plaintext highlighter-rouge">channel_reestablish</code> includes an explicit bitfield that lets a node
request <code class="language-plaintext highlighter-rouge">commitment_signed</code> only if it still needs it. This avoids
unnecessary retransmission, which is especially important for future
<a href="/en/topics/simple-taproot-channels/">simple taproot channels</a> where
retransmitting would require a full <a href="/en/topics/musig/">MuSig2</a> signing
round due to nonce changes. <a href="/en/podcast/2026/02/24/#bolts-1289"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>Bitcoin OptechThis week’s newsletter summarizes a discussion about recent OP_RETURN usage and describes a protocol to enforce covenant-like spending conditions without consensus changes. Also included are our regular sections describing recent changes to services and client software, announcing new releases and release candidates, and summarizing recent merges to popular Bitcoin infrastructure software.Bitcoin Optech Newsletter #392 Recap Podcast2026-02-17T00:00:00+00:002026-02-17T00:00:00+00:00https://bitcoinops.org/en/podcast/2026/02/2026-02-17-recap<p>Mark “Murch” Erhardt and Gustavo Flores Echaiz are joined by Sebastian
Falbesoner and Oleksandr Kurbatov to discuss <a href="/en/newsletters/2026/02/13/">Newsletter
#392</a>.</p>
<div id="podcast-links">
<a href="https://anchor.fm/s/d9918154/podcast/rss" title="Subscribe using RSS"><img src="/img/podcast/rss.png" alt="RSS icon" /></a>
<a href="https://podcasts.apple.com/us/podcast/bitcoin-optech-podcast/id1674626983" title="Subscribe using Apple Podcasts"><img src="/img/podcast/apple_podcasts.png" alt="Apple Podcasts icon" /></a>
<a href="https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9kOTkxODE1NC9wb2RjYXN0L3Jzcw" title="Subscribe using Google Podcasts"><img src="/img/podcast/google_podcasts.png" alt="Google Podcasts icon" /></a>
<a href="https://music.amazon.com/podcasts/d7540633-146f-4733-b716-4b38bafa8020/bitcoin-optech-podcast" title="Subscribe using Amazon Music"><img src="/img/podcast/amazon.png" alt="Amazon Music icon" /></a>
<a href="https://open.spotify.com/show/5UnB50h4O1jKaq5AyfN9Qo" title="Subscribe using Spotify"><img src="/img/podcast/spotify.png" alt="Spotify icon" /></a>
<a href="https://pca.st/tb9hbxoa" title="Subscribe using Pocket Casts"><img src="/img/podcast/pocket_casts.png" alt="Pocket Casts icon" /></a>
<a href="https://castbox.fm/channel/id5330863" title="Subscribe using Castbox"><img src="/img/podcast/castbox.png" alt="Castbox icon" /></a>
<a href="https://podcastindex.org/podcast/6071192" title="Listen on Podcast 2.0 players"><img src="/img/podcast/podcast-index.png" alt="Podcast Index icon" /></a>
<a href="https://anchor.fm/bitcoin-optech/" title="Listen on Anchor.fm"><img src="/img/podcast/anchor.png" alt="Anchor.fm icon" /></a>
</div>
<p><em>The Bitcoin Optech Podcast and transcription content is licensed Creative Commons <a href="https://creativecommons.org/licenses/by-sa/2.0/legalcode" target="_blank">CC BY-SA 2.0</a></em></p>
<audio id="player" controls="" type="audio/mpeg" src="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-1-24/418739898-44100-2-2a6577e48d595.m4a">
<a href="https://d3ctxlq1ktw2nl.cloudfront.net/staging/2026-1-24/418739898-44100-2-2a6577e48d595.m4a">
Download audio
</a>
</audio>
<div>
<h2 id="news"> News
</h2>
<ul>
<li id="proposal-to-limit-the-number-of-per-group-silent-payment-recipients" class="anchor-list">
<p>
<a href="#proposal-to-limit-the-number-of-per-group-silent-payment-recipients" class="anchor-list-link">●</a>
Proposal to limit the number of per-group silent payment recipients
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:13')" class="seek">1:13</a><noscript>1:13</noscript>)
<a href="/en/newsletters/2026/02/13/#proposal-to-limit-the-number-of-per-group-silent-payment-recipients">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#proposal-to-limit-the-number-of-per-group-silent-payment-recipients-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="blisk-boolean-circuit-logic-integrated-into-the-single-key" class="anchor-list">
<p>
<a href="#blisk-boolean-circuit-logic-integrated-into-the-single-key" class="anchor-list-link">●</a>
BLISK, Boolean circuit Logic Integrated into the Single Key
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('26:43')" class="seek">26:43</a><noscript>26:43</noscript>)
<a href="/en/newsletters/2026/02/13/#blisk-boolean-circuit-logic-integrated-into-the-single-key">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#blisk-boolean-circuit-logic-integrated-into-the-single-key-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="releases-and-release-candidates"> Releases and release candidates
</h2>
<ul>
<li id="bitcoin-core-29-3" class="anchor-list">
<p>
<a href="#bitcoin-core-29-3" class="anchor-list-link">●</a>
Bitcoin Core 29.3
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('49:18')" class="seek">49:18</a><noscript>49:18</noscript>)
<a href="/en/newsletters/2026/02/13/#bitcoin-core-29-3">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-29-3-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-0-2-2" class="anchor-list">
<p>
<a href="#ldk-0-2-2" class="anchor-list-link">●</a>
LDK 0.2.2
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('51:16')" class="seek">51:16</a><noscript>51:16</noscript>)
<a href="/en/newsletters/2026/02/13/#ldk-0-2-2">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-0-2-2-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="hwi-3-2-0" class="anchor-list">
<p>
<a href="#hwi-3-2-0" class="anchor-list-link">●</a>
HWI 3.2.0
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('52:20')" class="seek">52:20</a><noscript>52:20</noscript>)
<a href="/en/newsletters/2026/02/13/#hwi-3-2-0">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#hwi-3-2-0-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-inquisition-29-2" class="anchor-list">
<p>
<a href="#bitcoin-inquisition-29-2" class="anchor-list-link">●</a>
Bitcoin Inquisition 29.2
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('53:54')" class="seek">53:54</a><noscript>53:54</noscript>)
<a href="/en/newsletters/2026/02/13/#bitcoin-inquisition-29-2">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-inquisition-29-2-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes"> Notable code and documentation changes
</h2>
<ul>
<li id="bitcoin-core-32420" class="anchor-list">
<p>
<a href="#bitcoin-core-32420" class="anchor-list-link">●</a>
Bitcoin Core #32420
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('56:05')" class="seek">56:05</a><noscript>56:05</noscript>)
<a href="/en/newsletters/2026/02/13/#bitcoin-core-32420">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-core-32420-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="core-lightning-8772" class="anchor-list">
<p>
<a href="#core-lightning-8772" class="anchor-list-link">●</a>
Core Lightning #8772
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:02:29')" class="seek">1:02:29</a><noscript>1:02:29</noscript>)
<a href="/en/newsletters/2026/02/13/#core-lightning-8772">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#core-lightning-8772-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="lnd-10507" class="anchor-list">
<p>
<a href="#lnd-10507" class="anchor-list-link">●</a>
LND #10507
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:03:56')" class="seek">1:03:56</a><noscript>1:03:56</noscript>)
<a href="/en/newsletters/2026/02/13/#lnd-10507">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#lnd-10507-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4387" class="anchor-list">
<p>
<a href="#ldk-4387" class="anchor-list-link">●</a>
LDK #4387
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:05:48')" class="seek">1:05:48</a><noscript>1:05:48</noscript>)
<a href="/en/newsletters/2026/02/13/#ldk-4387">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4387-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4355" class="anchor-list">
<p>
<a href="#ldk-4355" class="anchor-list-link">●</a>
LDK #4355
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:08:14')" class="seek">1:08:14</a><noscript>1:08:14</noscript>)
<a href="/en/newsletters/2026/02/13/#ldk-4355">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4355-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4354" class="anchor-list">
<p>
<a href="#ldk-4354" class="anchor-list-link">●</a>
LDK #4354
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:09:21')" class="seek">1:09:21</a><noscript>1:09:21</noscript>)
<a href="/en/newsletters/2026/02/13/#ldk-4354">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4354-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="ldk-4303" class="anchor-list">
<p>
<a href="#ldk-4303" class="anchor-list-link">●</a>
LDK #4303
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:10:52')" class="seek">1:10:52</a><noscript>1:10:52</noscript>)
<a href="/en/newsletters/2026/02/13/#ldk-4303">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#ldk-4303-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="hwi-784" class="anchor-list">
<p>
<a href="#hwi-784" class="anchor-list-link">●</a>
HWI #784
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:13:10')" class="seek">1:13:10</a><noscript>1:13:10</noscript>)
<a href="/en/newsletters/2026/02/13/#hwi-784">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#hwi-784-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bips-2092" class="anchor-list">
<p>
<a href="#bips-2092" class="anchor-list-link">●</a>
BIPs #2092
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:15:02')" class="seek">1:15:02</a><noscript>1:15:02</noscript>)
<a href="/en/newsletters/2026/02/13/#bips-2092">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bips-2092-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bips-2004" class="anchor-list">
<p>
<a href="#bips-2004" class="anchor-list-link">●</a>
BIPs #2004
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:16:33')" class="seek">1:16:33</a><noscript>1:16:33</noscript>)
<a href="/en/newsletters/2026/02/13/#bips-2004">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bips-2004-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bips-2017" class="anchor-list">
<p>
<a href="#bips-2017" class="anchor-list-link">●</a>
BIPs #2017
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:19:44')" class="seek">1:19:44</a><noscript>1:19:44</noscript>)
<a href="/en/newsletters/2026/02/13/#bips-2017">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bips-2017-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
<li id="bitcoin-inquisition-99" class="anchor-list">
<p>
<a href="#bitcoin-inquisition-99" class="anchor-list-link">●</a>
Bitcoin Inquisition #99
(<a href="javascript:void(0)" title="Play this segment of the podcast" onclick="seek('1:26:53')" class="seek">1:26:53</a><noscript>1:26:53</noscript>)
<a href="/en/newsletters/2026/02/13/#bitcoin-inquisition-99">
<i class="fa fa-link" title="Link to related content"></i>
</a>
<a href="#bitcoin-inquisition-99-transcript">
<i class="fa fa-file-text-o" title="Read this segment of the transcription"></i>
</a>
</p>
</li>
</ul>
</div>
<h2 id="transcription">Transcription</h2>
<p><strong>Mark Erhardt</strong>: Good morning, this is Bitcoin Optech Newsletter #392. Today,
we’re going to talk about a proposal to limit the silent payments recipients,
and we’re talking about BLISK, a boolean circuit logic integrated into a single
key. And we have a few Release candidates and a bunch of Notable code and
documentation changes for you, especially LN stuff this week. So, let’s get
right into it. We are joined by two guests, Sebastian and Oleks. Would you
like to introduce yourselves?</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, I’m Sebastian. I’m a many years’ Bitcoin Core
contributor and also a little more into libsecp lately. And I’m funded by
Brink.</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, my name is Oleks. I have recently joined
Blockstream as a cryptography researcher. In the past, I also made a lot of
tricks with Bitcoin and zero-knowledge proofs (ZKPs), but yeah.</p>
<p><strong>Mark Erhardt</strong>: Thank you. Thank you for joining us. Also with us is Gustavo
today again.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Hi, Murch. Hi, everyone. Thank you for having me.</p>
<p id="proposal-to-limit-the-number-of-per-group-silent-payment-recipients-transcript"><em>Proposal to limit the number of per-group silent payment recipients</em></p>
<p><strong>Mark Erhardt</strong>: Wonderful. So, let me get to the first News item. We’ve seen
a discussion, I think we reported on it a few times already, and the context is
for silent payments, when you have multiple recipient outputs that are all going
to the same silent payments recipient, it could become quite expensive for that
recipient to scan the silent payments outputs. And there is now a proposal to
limit the number of outputs that can go to a single recipient to 1,000.
Sebastian, you’ve been looking at this for some time. Can you provide a little
more context on what exactly the issue is here and maybe why it only affects a
single recipient? You do have to scan all P2TR outputs anyway, right?</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, so for the historical background, in libsecp,
the cryptographical library used in Bitcoin Core and the wider Bitcoin
ecosystem, we have been working on implementing a silent payments module for
quite a while now. I think it is at least two years. Yeah, I know, getting
late! At least two years, we have reached take four or five already; well, take
five having been closed recently.</p>
<p><strong>Mark Erhardt</strong>: Let me jump in there right now. So, we’ve been promised
silent payments. How come this is taking so long? What’s the problem? Who do
we have to lean on to?</p>
<p><strong>Sebastian Falbesoner</strong>: Two weeks, TM! Yeah, so I think we’re quite far
already, but within the last months, one reviewer found a potential issue on the
recipient side, on the scanning side. So, the issue is, it could perform quite
bad in the worst case, the worst case being that a sender crafts a transaction
that fills out a whole block, like maxing out the consensus limit of 1
mega-vbytes. So, this will be a transaction that is non-standard, because the
non-standard limit is 100 kvB (kilo-vbytes). And if a sender crafts a
transaction where all the recipients are going to one entity, one group – so to
give a little context in silent payments, a recipient address not only consists
of one public key, but two. So, there is a scan public key and the spend public
key, and a group is defined as all recipients that share the same scan public
key. The spend public key can be different due to a mechanism called labeling,
like you can tweak spend pubkeys. So, it’s a little cheaper to scan, so it’s
meant as a mechanism to differentiate the incoming payments. So, it shouldn’t
be confused with accounts, because there are privacy drawbacks.</p>
<p>But yeah, to come back to the topic, so we found that if such an adversarial
transaction is created with a little more than 23,000 outputs, or it’s a little
more, I don’t know the exact number now in my head, but so you just divide the
maximum block space by the space it will take for one taproot output, because
silent payments only creates taproot outputs.</p>
<p><strong>Mark Erhardt</strong>: Yeah, I think 23,000-something is right.</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, something a little more than that, assuming that
one taproot output takes 43 vbytes, I think. And yeah, so the scanning we do
currently in the module is we go through all the transaction outputs and see if
there is a match. And doing that is not just comparing a fixed output, there is
some elliptic curve calculation included to detect labels. So, we just have
first an unlabeled output candidate and we subtract that from each candidate in
the output, and then we look if the result is in one of our labels in our label
cache. So, for each output, there is some quite expensive elliptic curve
operation to be done for each output. And yeah, if we assume now we have a
match, we have to do the same thing again because we derive a different tweak.</p>
<p><strong>Mark Erhardt</strong>: Right, let me jump in briefly and give a little more context.
So, in silent payments, the nifty thing is we get reusable addresses, because we
can send to the payment instructions multiple times without it looking like the
same output script onchain. And the way it works is that it takes all of the
public key information and creates an Elliptic Curve Diffie-Hellman with a key
exchange with the recipient public key; we’ll talk more about ECDH in just a
little while. And so, the recipient basically just checks, “If I try to do a
key exchange with my public key and the information from the inputs, does any of
these outputs look like it’s paying me with that construction”, right? So, this
is unique because the inputs are always required to be unique, you can never
spend the same UTXO twice. So, if a UTXO is spent, the output will be unique.
But if you paid the same recipient multiple times, it would generate the same
output script. So, the way we get around this is we increment a counter for
every time someone is paid. We tweak it with a +1 basically, and that way we
get a new output script every single time. And for everyone else, it looks
indistinguishable from any other P2TR output.</p>
<p>So, the way I understand you here is, we have to scan them in order. Now, I’m
curious, wouldn’t it work that we require payments to the same recipient to be
in order? Like, sure, if you’re paying five people, it could be Alice, Bob,
Carol, then me, and then me again. But couldn’t we just require that outputs
are ordered in the order that they are going?</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, that was another suggestion in the more recent
discussion. But that would be a far more invasive change because the BIP is
already out for some time and the BIP says the order doesn’t matter.</p>
<p><strong>Mark Erhardt</strong>: Unfortunately, you always learn more the longer you’re
pursuing an idea!</p>
<p><strong>Sebastian Falbesoner</strong>: Yes. If we do that, we called it the ordered K idea
and the limited K idea, so we even had these fancy names already. But the
ordered K would be very invasive. I think there were some privacy issues
raised, I’m not sure if they are based on a good foundation, but I think my
prime argument would be it’s too late for that.</p>
<p><strong>Mark Erhardt</strong>: Well, because silent payments hasn’t been adopted that broadly
yet. There’s probably like three wallets that use it so far.</p>
<p><strong>Sebastian Falbesoner</strong>: Maybe it’s still possible, yeah. I think one argument
was also that it’s more secure on the sender side of the libsecp API if we do a
limited K because we can error out if it’s not respected. Whereas in the
ordered K, we can create some result, but we would still have to give
guarantees, “Oh, please never modify the order of this”. So, it’s much more in
the hands of the upper layer to follow whatever we write in the docs.</p>
<p><strong>Mark Erhardt</strong>: Right. For example, Bitcoin Core will shuffle the outputs on
a transaction.</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, for example, yeah. So, things like those you
cannot do anymore. Also, I don’t know if you think about batch transactions on
exchanges. I don’t know if they shuffle outputs or not, but one would have to
be really careful to then keep the order, as otherwise payments cannot be found.</p>
<p><strong>Mark Erhardt</strong>: Right. Or, or if someone does a coinjoin and multiple people
happen to pay – well, never mind, they’d have to coordinate them anyway to
tweak the number.</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah. I’m not familiar with those details of
coinjoins, if there is some ordering, sorting or randomizing included or not,
but yeah.</p>
<p><strong>Mark Erhardt</strong>: Right. So, basically the concern is the recipient would have
to scan all outputs. And then, let’s say on the last one, the recipient finds a
payment to themselves. And then they’re like, “Well, there could be a second
payment”, and now they have to scan all of them again. So, with 23,000
payments, if they were ordered exactly reverse and it scanned in the correct
order, then it would always be super-slow.</p>
<p><strong>Sebastian Falbesoner</strong>: Yes, to give some concrete numbers here, I think it
was in the range of about 10 minutes, 9 to 10 minutes on a more modern machine.
And one first optimization you can do is just randomize the outputs, because
then finding one K is already cut in half. So, I think it’s close to
n<sup>2</sup>-half in the worst case, like you don’t always go to the end, but
always closer to the end.</p>
<p><strong>Mark Erhardt</strong>: So, of course if he’s nice to you and actually orders them in
the right way, then it also takes much longer.</p>
<p><strong>Sebastian Falbesoner</strong>: Yes. So, with that, we could go down from roughly 10
to 5 minutes, but that’s still kind of not ideal. So, I think it’s hard to
reason what is the right number, but I don’t think we want to be on the same
order of magnitude of the block time, if that makes sense, right? I mean, it’s
still an unanswered question, “What is a good range to be in?”</p>
<p><strong>Mark Erhardt</strong>: So, what would be the constraint here? So, the recipient gets
paid by you 23,000 times, and on the machine where they scan for silent
payments, they’ll now be slow. So, if this is an exchange, hopefully they have
a separate machine to scan for silent payments, and some of the silent payment
recipients might be informed a few minutes later. If it’s a home user, congrats
on getting paid 23,000 times.</p>
<p><strong>Sebastian Falbesoner</strong>: I mean, one detail to that, it doesn’t necessarily
mean that the funds go to the recipient. You could have 20,000 outputs with
zero sets, right, because there is no reason to respect the dust limit. It’s a
non-standard transaction anyway already. And it could be that only in the last
find, there is some bigger amount that it’s worth it scanning. I guess you
could apply some filter and say if the total amount is below that and then
threshold, then just skip it, it’s not worth it. But it’s not necessarily that
a high amount of funds go to the recipient. The main cost is the fees, or the
bribe for the miner to include the block. It’s a non-standard transaction.</p>
<p><strong>Mark Erhardt</strong>: It could even be worse, you make 23,000 payments to the
recipient that are all zero sets and then the last payment goes to someone else.</p>
<p><strong>Sebastian Falbesoner</strong>: Yes, that is also very much possible.</p>
<p><strong>Mark Erhardt</strong>: Right. So, why still 1,000? Isn’t it maybe a little
unexpected? We see very few transactions where there are 1,000 payment outputs
in the first place. Why would anyone ever need to pay 1,000 people on the same
scan key?</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah. One thing that was brought up, if one exchange
sends to another exchange with a large batch transaction, I mean, I guess they
wouldn’t want to use non-standard transactions, but that was one thing that was
brought up. And in general, the 1,000 number is still more of a placeholder. I
mean, I know in the newsletters it was stated as it was my concrete suggestion,
but I gave the feedback, “Oh, let’s keep it as my suggestion. If we say it’s a
concrete one, then maybe it’s easier to get feedback”.</p>
<p><strong>Mark Erhardt</strong>: I don’t know, it seems still pretty big.</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, I think I wouldn’t have sleepless nights if we
go to the order of hundreds or something.</p>
<p><strong>Mark Erhardt</strong>: Yeah, 200 or something would probably be fine.</p>
<p><strong>Sebastian Falbesoner</strong>: One other suggestion was to just take a tenth of the
maximum. So, we would still have the worst-case standard transaction size. So,
that would be 2,350-something. But yeah, I’m not sure if that’s really
necessary. It’s now a trade-off of what worst-case time are we willing to
accept. So, with 1,000, we are at 30 seconds unoptimized. With the randomizing
of the outputs, we are on roughly 15 seconds. And then, there is one other
interesting optimization that helps both for the worst and the average case.
That is a batch inversion. And then, that brings another 2.5X improvement.</p>
<p><strong>Mark Erhardt</strong>: Batch inversion being, you find the first output and then you
scan, is it the next one or is it the previous one?</p>
<p><strong>Sebastian Falbesoner</strong>: It’s more like after you do these elliptic curve point
additions, you’re in some internal representation, Jacobian coordinates, and you
have to transfer those back to a fine coordinate, like only with XY constants to
serialize them, so that the label cache lookup can be done. And that needs one
inversion per each transaction output, and you could do those in batches. So,
you do that within a single K-value that you look to this inversion at several
outputs at once, which is significantly faster.</p>
<p><strong>Mark Erhardt</strong>: And the inversion is always different for each tweak, right?
You couldn’t just scan for the first 10 tweaks on every output right away?</p>
<p><strong>Sebastian Falbesoner</strong>: Yes. So, it’s the result of a calculation where the
thing you subtract from the text output is different for each K-value. But for
that reason, yeah, it helps also for the average case.</p>
<p><strong>Mark Erhardt</strong>: All right. And this is holding up silent payments now?</p>
<p><strong>Sebastian Falbesoner</strong>: I think so. Yeah, I’m pretty positive that this is
one of the last blockers. Yeah, we did quite spend a long time on alternative
scanning approaches. So, there is a thing where you do the scanning in the
other direction, where you loop over the labels and look at the result, “Oh, is
any of this result in my transaction outputs?” And this has the drawback that
it scales not well with the number of labels. So, for use cases with many
labels, it gets slower and slower with each additional label. And the
functionality as described in the BIP that we implemented, it’s basically
independent of the number of labels because the lookup is done in a hash map.
So, that has a nice 01 lookup cost property.</p>
<p>In retrospect, I regret a little that we spent so much time into looking that we
could have proposed a protocol change earlier, but I don’t know, in my head it
was like, “Oh, that’s too late already. That would be silent payments v1
already, like the next version”.</p>
<p><strong>Mark Erhardt</strong>: But seriously, yes, it’s implemented now by, I believe,
Sparrow, by CakeWallet, and I think Nunchuck just announced that they
implemented it. But let’s say you start using v2 now and v2 requires that it’s
ordered or limited to 200, or whatever you decide in the end. And for the ones
that ruled it out, sure, maybe I assume the silent payments address would have
to change for the users, but the implementation cost of that I assume would be
pretty low.</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah. I mean, the plan now is to not change the
version, because we are reasonably confident, or maybe there will be still some
feedback that indicates otherwise. But so far, it seems like no one even
creates transactions with more than one recipient.</p>
<p><strong>Mark Erhardt</strong>: Right. Wouldn’t it also be pretty easy to, if you ever see a
transaction that is this big, you ignore it and just scan it in the background
in chunks or something?</p>
<p><strong>Sebastian Falbesoner</strong>: You mean like do that on a separate thread?</p>
<p><strong>Mark Erhardt</strong>: Yeah. Like, I mean most of the time I think we don’t see
transactions with that many payment outputs anyway. But then, if you do, how,
how urgently do you usually need to know that you got paid? Can you not just
chunk it in and scan in background?</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah. I mean, this would probably introduce a code
path that it’s so rarely executed that I don’t know, you cannot even test it.
But yeah, so far there was explicit feedback from two developers that said
they’re fine with the limit. They cannot think of any use case. There was one
slightly related feedback about we need good API documentation, because the
current scanning API is capable of scanning hundreds of thousands of labels
easily. But if everyone using that API hands out and creates that many labels
already, then that might be not interoperable with every type of wallet. So,
for example, light clients, they are more restricted in the number of labels
they can use. So, it’s important that we point that out. Like, if you create a
lot of labels, then don’t expect that every wallet that will ever exist will be
able to import and scan for those.</p>
<p><strong>Mark Erhardt</strong>: When you’re talking about API, you’re now talking about the
API of libsecp, right?</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah.</p>
<p><strong>Mark Erhardt</strong>: Yeah, okay, thank you. So, users of libsecp would be
predominantly Bitcoin Core, but also other Bitcoin projects that use libsecp or
wrap libsecp for crypto.</p>
<p><strong>Sebastian Falbesoner</strong>: Yes, exactly.</p>
<p><strong>Mark Erhardt</strong>: So, the next step would be to decide what the actual limit is
and to improve API documentation to release libsecp and roll out the silent
payments?</p>
<p><strong>Sebastian Falbesoner</strong>: Yes. Just yesterday on the PR, it’s PR #1765. I
think on libsecp, I proposed a limit of 1,000. I proposed API documentation and
there’s been positive feedback so far, but maybe I’m sure there will be some
more bike-shedding. One open question might be, if you find a transaction that
exhausts the K limit, wouldn’t users want to look ahead and see, “Oh, it could
be that there is still something hiding in the more than K_max”, so would we
want to provide recovery tools for that, or something? But that would
complicate the API. But I guess there will be some bike-shedding discussion
about that.</p>
<p><strong>Mark Erhardt</strong>: I mean, it’s a little bit sort of a discussion similar to, you
give an address to someone else and they interpret it to construct a different
output script. Like you tell someone, “P2TR public key”, and they P2PKH
instead. It’s like, “You’re not following my instructions on how I want to be
paid. Did you actually pay me or not?” Like, if you go and dig a hole in my
backyard because you have my address and bury money there, did you pay me when
you were supposed to drop it into my mailbox?”</p>
<p><strong>Sebastian Falbesoner</strong>: Yes.</p>
<p><strong>Mark Erhardt</strong>: I feel like it’s good to think about this, but just imposing a
limit and widely communicating that you shouldn’t pay more than 1,000 times to
the same recipient seems like doing more than this might be overthinking.</p>
<p><strong>Sebastian Falbesoner</strong>: Yes, I agree, but I wouldn’t be surprised if that
comes up in the discussion. But other than that, I would hope that we are ready
soon. That was one of the major blockers over the last few months, I would say.
I mean, the investigating of alternative scanning approaches was interesting.
It led to a lot of benchmarking data.</p>
<p><strong>Mark Erhardt</strong>: I see you’re following the tradition of other Bitcoin
developers that say something is engineered properly when it’s over-engineered
140%!</p>
<p><strong>Sebastian Falbesoner</strong>: Yeah, I guess you could say so, yeah.</p>
<p><strong>Mark Erhardt</strong>: All right. Gustavo, Alex, do you want to chime in on this
one?</p>
<p><strong>Gustavo Flores Echaiz</strong>: No, I think it was quite clear, thank you.</p>
<p><strong>Mark Erhardt</strong>: All right. Do you have any call to action or other
information to share, Sebastian?</p>
<p><strong>Sebastian Falbesoner</strong>: One small thing. I’m trying to make a signet block
with that exact attack. I’m just still working on including it. It’s
non-standard, so I have to bribe a signet miner to include it, but once that is
ready, I will post it on the mailing list with all the key material and the
label data needed, so other wallets can see if they are affected by this attack.
Or maybe it reveals other things, right? If you get paid 20,000 times per
transaction, even if you don’t have an issue in scanning, it could be that it
reveals that, I don’t know, your GUI is crashing because it’s not prepared to
get 20,000 times in a single transaction. So, once that is ready, I will share
that as well. And otherwise, if there are no further objections, I think we
will introduce either that limit or a similar one and, yes, hopefully be able
soon to ship the silent payments module in libsecp.</p>
<p><strong>Mark Erhardt</strong>: Are you worried about popularizing the attack by talking about
it so much?</p>
<p><strong>Sebastian Falbesoner</strong>: No.</p>
<p><strong>Mark Erhardt</strong>: Okay.</p>
<p><strong>Sebastian Falbesoner</strong>: It’s an unusual attack. Also, something to point out,
I don’t know if I mentioned that in the mailing list attack, all the others are
not affected. It’s only affects that single targeted entity.</p>
<p><strong>Mark Erhardt</strong>: Right. It only affects the recipient that is being paid
actually. And you still have to buy all that blockspace, right?</p>
<p><strong>Sebastian Falbesoner</strong>: Yes.</p>
<p><strong>Mark Erhardt</strong>: I mean, 20,000 outputs at 43 bytes is still, well, the whole
block is 1 million bytes, so it’s a hundred thousand sats, even at 0.1 sat/vB
(satoshi per vbyte), which seems unlikely.</p>
<p><strong>Sebastian Falbesoner</strong>: I would be very surprised if we ever see that attack
on mainnet. But better to be prepared for it than not.</p>
<p><strong>Mark Erhardt</strong>: Okay. Now, stop delaying silent payments!</p>
<p><strong>Sebastian Falbesoner</strong>: Yes. Two weeks, TM!</p>
<p><strong>Mark Erhardt</strong>: Okay. No, I’m still very excited for that to roll out more
broadly. I think it’s one of the more exciting privacy techniques that has come
up in the last few years. All right. Thank you, Sebastian, for joining us.</p>
<p><strong>Sebastian Falbesoner</strong>: Thanks for having me.</p>
<p id="blisk-boolean-circuit-logic-integrated-into-the-single-key-transcript"><em>BLISK, Boolean circuit Logic Integrated into the Single Key</em></p>
<p><strong>Mark Erhardt</strong>: We’re going to talk about BLISK next. You can stick around or
not. See you! All right, cool. As I said already, we’ll be talking about,
“Boolean circuit Logic Integrated into the Single Key” with Oleks, and this is
called BLISK. You posted on Delving Bitcoin about BLISK. And the idea here is
with MuSig and FROST, you can create threshold signatures and multisignatures in
the sense that you can design a certain number of keys to form a quorum. So,
you can do with FROST things like 3-of-5; with MuSig, you can only do n-of-n so
2-of-2, 4-of-4, 16-of-16. And with BLISK, you described that you can construct
a boolean logic where you can use logic AND and logic OR to combine keys into,
well, logic expressions, boolean expressions, I should say. I read that you use
ECDH to construct the OR gates and you use MuSig2 to construct the AND gates.
And that’s about all that I understood from this. Oh, and onchain, you only see
a single public key. You only need to accept a single signature, but offchain,
the participants in the output script have to construct that output script in
some manner. So, I’m curious, how much effort is that whole out-of-band setup
there?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, basically we started this research more than one
year ago and initially we tried to resolve another problem, totally another. We
worked on verifiable key agreement mechanism. For example, if you’re operating
in the chat and you have like many, many different participants, to make your
networking efficient, you need to have a kind of broadcast encryption key. And
if each participant controls their own key, you need to have this verifiable key
establishment mechanism. And if you want to have a robust environment, where
nobody can break the system on their own, you need to combine all keys together
to receive a single value and use it for broadcast encryption. And then, we
decided to see on this problem from a different angle. We came to the idea,
okay, if Alice – so ECDH, that’s literally what an OR gate does. Because if
you have Alice and Bob and they are combining their secrets and their public
keys to the single value, if we are asking who exactly can access the key: Alice
or Bob, because Alice can derive the same key and Bob can derive the same key.
So, that’s literally what an OR gate does.</p>
<p><strong>Mark Erhardt</strong>: Right. So, an Elliptic Curve Diffie-Hellman handshake creates
a shared secret, which is produced from the public key of one side and the
private key of the other side. So, I only got it now when you explained it, but
the OR gate basically is, “I know the public key of Alice. So, it’s either
Alice’s public key and my private key, or Alice knows my public key, so Alice’s
private key and my public key can also construct a shared secret”. Okay, that’s
pretty cool. Go on.</p>
<p><strong>Oleksandr Kurbatov</strong>: And that’s very important that only Alice or Bob can
derive the same key. So, Carol cannot do that, Dave cannot, etc. Then, we have
looked on multisignature n-of-n constructions. And that’s literally what an AND
gate does. Because if we have Alice and Bob and key aggregation mechanism like
MuSig2 key aggregation mechanism, and if we are asking who exactly can produce
the signature: Alice plus Bob. So, Alice cannot do that without Bob, Bob cannot
do that without Alice, only them together. And yeah, logically, we decided to
build a tree or a kind of a circuit where each gate can be represented as an
ECDH or MuSig2 aggregation mechanism. And basically, it worked. So, right now
you can define the list of public keys of all participants. So, Alice, Bob,
Dave, Carol, etc. Then you can write the logic how exactly you want to see your
policy, so who exactly must co-sign the transaction to have a valid signature.
And then, you need to compile everything. One missing component is ZKPs,
because when you are constructing ECDH secret, you need to prove that you have
constructed that in the right manner. Basically, that’s it.</p>
<p><strong>Mark Erhardt</strong>: So, how are they compiled into a single public key then? Is
it just an addition of the public keys? I would assume that that can’t be it,
because then maybe there would be cancellation attacks or things like that. So,
at a high level, could you explain how you go from the boolean logic to a single
public key?</p>
<p><strong>Oleksandr Kurbatov</strong>: Right. Just imagine the tree and we have public keys of
each participant, except tree leaves. And then, we need to calculate values in
nodes. And there is dependency on what kind of node we want to calculate,
because for n nodes, we need to make a key agreement or a key aggregation
mechanism, like MuSig2. But if you’re operating with OR gate, definitely Alice
or Bob, so one of the children, should calculate this secret and appropriate
public key. And that’s why we need ZKPs, because we require only one party to
calculate the common secret. But no one should be able to forge the tree
itself.</p>
<p>So, yeah, definitely we need to first of all define how exactly we need to
calculate appropriate nodes in the tree. And one additional note that we need
to represent this circuit in CNF form, this Conjunctive Normalized Form. It
means we need to have only one AND root gate with a lot of children OR gates.
So, yeah, it’s kind of like trusted setup, but this is not a trusted setup
because we are using bullet proofs. For example, you can use any proof
framework which doesn’t require you to have this toxic waste and trusted setup,
so it can be completely verifiable, but this is setup. So, you cannot take only
one coordinator who will calculate an entire circuit. You need all parties,
like not all parties, but enough forum of them to collaborate, create the final
public key.</p>
<p><strong>Mark Erhardt</strong>: So, basically, all of the involved participants agree on the
boolean expression that they want to implement, then all of them have to
participate at various steps, either to contribute to the OR constructions or
the AND constructions. And then, you use ZKPs to prove that every party
participated correctly for the parts that others cannot look into. When we talk
about trusted setup, for example, in the context of Zcash, there is a group, an
in-crowd that creates the circuit that is used by everyone later. But in this
case, the people that rely on this expression are also participating. So, in a
sense, it’s like a trusted setup, but only for the people that are in the
trusted crowd, right?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, definitely. Everybody should agree on the same
policy. It’s how organizations operate. Because we have, I don’t know, CEO
signature is required plus, I don’t know, CFO plus CMO, etc. So, all parties
are already agreed with the defined policy, and this is totally fine. It’s how,
for example, we just created the multisignature. We agreed that we’re going to
use this public key, that’s the kind of agreement, and we have the same type of
agreement in the BLISK. So, all parties need to make a short interactive round
to compute the final public key. And then, what is very interesting is that you
can then update the key without interactions with other parties. If, for
example, only my key should be changed because, I don’t know, the previous was
compromised or, I don’t know, I have lost it, I don’t need to re-DKG
(Distributed Key Generation). So, BLISK doesn’t require DKG, I can operate with
existing key. I don’t know, I have used that ten years and I can easily connect
it to the BLISK instance.</p>
<p><strong>Mark Erhardt</strong>: But that generates a new output script, right?</p>
<p><strong>Oleksandr Kurbatov</strong>: What do you mean by the output script?</p>
<p><strong>Mark Erhardt</strong>: So, the output script, the scriptPubKey that people pay to in
the end is a product of all the input public keys and the boolean logic, right?
So, if you change one of the keys, it would be a new output script, right?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, that’s right. I mean, for example, if you have
already set up this public key to the smart contract, you can easily update
that. In the case of Bitcoin, you need to have enough quorum to co-sign the new
transaction, to transfer money to the new P2TR address.</p>
<p><strong>Mark Erhardt</strong>: Sure, but you need to tell everyone else that you update your
key, because they wouldn’t be tracking it anymore. So, the non-interactive part
is you can unilaterally propose it, but everybody else is involved again in
this.</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, I mean for example, in Frost, if you’re updating
your own key, you cannot do that without involvement of all parties, because
everybody participates in your DKG procedure. In this case, all other keys can
remain the same, but only my part will be updated. So, I don’t need them to
store new secrets, new key shares, such like, so we don’t need that.</p>
<p><strong>Mark Erhardt</strong>: Right, but they do need to sort of be aware of the new tree
construction and what outputs to scan. Yeah, cool. So, the big advantage here
is, of course, that you can have more complex restrictions or constructions than
just with two out of these three or all of these. Where do you anticipate this
BLISK will be used? Because it sounds to me like the setup for these output
scripts is pretty heavy with ZKPs and first coming to agreement what the policy
should be. Sounds like maybe manual even.</p>
<p><strong>Oleksandr Kurbatov</strong>: I have attached benchmarks in the paper and definitely,
yeah, you’re totally right. Everything depends on the policy you want to have.
If this policy is complex, I don’t know, it requires, I don’t know, a large pool
and circuit, definitely the setup takes more time. The signature process will
be like very easy, so it’s just an instance of MuSig2 solution. But the setup
will be harder and harder depending on the complexity of the circuit. But for
example, for real life examples, if you want to emulate threshold 2-of-3 with
this construction, or Alice plus Bob or Carol, setup takes milliseconds. And
so, yeah, it can be done by, I don’t know, any device. So, the proving system
is not quite difficult. So, you’re not proving, I don’t know, the KVM execution
trace. You’re proving only the simple operations: ECDH and that’s it. You can
prove that efficiently.</p>
<p><strong>Mark Erhardt</strong>: Right. So basically, if a wallet wanted to implement this,
onchain it looks completely the same. All of the complexity is out of band with
the setup where now they might need to be able to verify a ZKP that proves that
the ECDH was done correctly, which probably wallets wouldn’t have yet, but could
perhaps get through some library, like libsecp or similar. And then, the
signature is basically, you just sign regularly and it gets aggregated according
to the circuit?</p>
<p><strong>Oleksandr Kurbatov</strong>: The same process as in MuSig2. It’s just a schnorr
signature. So, verification is the same, so yeah, no difference.</p>
<p><strong>Mark Erhardt</strong>: So, when you set up a boolean logic policy like that, would
you be able to have key derivation on top of that? So, you can basically have a
single output script that is the zeroth iteration of it and then you just tweak
it differently, like extended public key sort of stuff?</p>
<p><strong>Oleksandr Kurbatov</strong>: That’s a good question. You can tweak that, no
problems. But for example, it has the same problem as silent payments have.
So, for example, you cannot P2TR, where is the multisignature behind. So, if
this taproot is like aggregated MuSig2, you cannot pay the silent payment to
this address because they cannot derive an appropriate ECDH and receive a new
key.</p>
<p><strong>Mark Erhardt</strong>: Sure.</p>
<p><strong>Oleksandr Kurbatov</strong>: The same here. So, the final public key, you cannot
just create ECDH with this public key and pay, I don’t know, silent payments to
this address. So, the tweaking can be done, but the amount of techniques is
limited so you can do it properly.</p>
<p><strong>Mark Erhardt</strong>: But it sounds to me like you could at least use it as a
generator for many different output scripts so you don’t get massive address
reuse, with just incrementing or labeling.</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah. I need to think.</p>
<p><strong>Mark Erhardt</strong>: I’m just jumping into new topics here. Okay, so basically the
idea is maybe this could be used at a enterprise level set up or for smart
contracts, or do you think this would be interesting maybe as a bridge setup
technique, or how do people use this in the future?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah. For me, like, what’s the most important part?
You cannot express real life by the pure threshold signature. So, if you have a
condition, Alice or Bob and Carol or Dave should sign, you cannot express a
simple policy by threshold signature. That’s not possible at all. It means if
you need to have something more flexible than pure, you’re going to use BLISK.</p>
<p><strong>Mark Erhardt</strong>: Well, you could do it in a script leaf of course currently,
but that would require leaking a lot more information on what’s going on under
the hood, and it would be more expensive onchain. The big advantage here would
be the complexity moves out of band and you don’t reveal what’s the business
logic underneath. But we could do something like this currently with script,
just not as elegantly.</p>
<p><strong>Oleksandr Kurbatov</strong>: The reason why we like MuSig2 or FROST is because they
are hiding the policy behind. So, we can verify only the single signature, but
we have no clue how many participants participated to produce the signature.
The same in that, you can hide the policy itself, because the verifier can
verify only the single signature. You don’t reveal anything about your policy
structure, about your organization structure, so this data is hidden. And
probably, that’s just beautiful, yeah.</p>
<p><strong>Mark Erhardt</strong>: Right. So, you posted to Delving about this, you mentioned
the paper. So, is the next step that this is going the academic research route,
or you also have a proof of concept; are you working on a project that is making
use of this, or how does this fit into the bigger picture?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah. We have already done a compiler so you can define
the set of public keys, you can write the boolean policy and it will compile
with the single public key. So that’s already done. That’s not a
production-ready framework, so it’s not recommended to use it in your wallets or
applications because it’s not audited, battle-tested, etc. But we’ve just shown
that it’s possible, and we use it for benchmarking of different constructions.
Recently, just yesterday, I came with the idea that this approach can be
extended with DLC contracts. So, you can combine some, I don’t know, events
from the real world with the policy defined before in BLISK and combine more
interesting, I don’t know, cases, etc. So, probably we will research a bit in
this direction. Yeah, finally, I have no clue how it will be used, but I see
potential in this approach. Let’s see.</p>
<p><strong>Mark Erhardt</strong>: Right. So, basically, you’re providing this new primitive,
and now people tend to be pretty creative with this sort of stuff, and you’re
just waiting to see what’s coming. Cool. Do you have a call to action, or are
you asking for feedback, or what would you like to see as the next step?</p>
<p><strong>Oleksandr Kurbatov</strong>: I don’t know. Everything is open source right now, so
everybody can reuse that. It was just research we were interested in. So,
yeah, the public could use it wisely.</p>
<p><strong>Mark Erhardt</strong>: Oh, maybe one more question. So, one of the things that
people have been doing is provide security proofs of this. Is there a security
proof for this construction already?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, in the paper. Yeah, one more interesting point,
that we’ve just shown how you can combine MuSig2 and ECDH, but you are not
limited only with those primitives. If you have, for example, a post-quantum
multisignature scheme and post-quantum key encapsulation mechanism, you can do
the same. So, you’re not limited only with elliptic curve points. If you have
those primitives, that’s it. So, you can have a post-quantum BLISK, and it will
work fine.</p>
<p><strong>Mark Erhardt</strong>: All right. Well, that’s pretty cool research. Thank you for
sharing. Gustavo, do you have anything else on this?</p>
<p><strong>Gustavo Flores Echaiz</strong>: No, this is a very fascinating idea, so thank you for
sharing that. Well, maybe my only question would be, do you see any limitations
to this protocol that you invented? How far could someone take it?</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, probably the biggest limitation I see right now is
it’s hard to support this technology, for example, by Hardware Security Modules
(HSMs). Because if you’re operating with FROST signature or with MuSig2, each
HSM can produce their own signature and coordinator will aggregate everything.
But if you want to support other cryptographic constructions, like ECDH
derivation, etc, plus some interactive rounds, at least set up, you need to use
the software and hardware which is ready to support it. Right now, it’s not
possible, it’s not feasible. So, it has some drawbacks comparing to existing
multisignatures and threshold signatures, but yeah, for wallets, it doesn’t
matter; I mean for mobile wallets, for software wallets. So, yeah.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Makes sense. Thank you so much.</p>
<p><strong>Mark Erhardt</strong>: All right. Thank you for joining us and telling us about
BLISK. We will be moving on to the Releases and release candidates section.
You’re welcome to hang on, but if you have other things to do, we totally
understand. Thank you for your time.</p>
<p><strong>Oleksandr Kurbatov</strong>: Yeah, thanks for having me. Take care.</p>
<p><strong>Mark Erhardt</strong>: All right. Gustavo, do you want to take it from here?</p>
<p id="bitcoin-core-29-3-transcript"><em>Bitcoin Core 29.3</em></p>
<p><strong>Gustavo Flores Echaiz</strong>: Yes, I do. Thank you, Murch. So, this week we have
four different releases, the first one being Bitcoin Core 29.3. So, this is a
maintenance release of a previous major release series. And here, there’s
multiple bug fixes that are included. The main ones are those that were related
to the wallet migration bug that was discovered in v30 and v30.1. So, as much
as some bugs only applied to 30 and 30.1, the fixes were backtracked to apply to
29.3 so that we could just adapt to the new mitigations that have been put in
place for this bug. Also, you can check out the Newsletter #387 for more
context on this issue. And also, specific on the News section, we covered that
incident, but also we covered the PRs that were used to fix that bug.</p>
<p>Also, another important part of 29.3 are the per-input sighash mid-state cache
that reduces the impact of quadratic sighashing in legacy scripts, and the
removal of peer discouragement for consensus-invalid transactions. What does
that mean? So, CVE-2025-46598 was disclosed late last year, where it was
discovered that a CPU DoS (Denial of Service) attack from unconfirmed
transaction processing was possible. It was judged low severity, but basically
this maintenance release 29.3 also includes the fixes that came for that
specific issue. So, you can check out the release for more details, but this is
basically just a maintenance release that backtracks a few fixes on 29.</p>
<p id="ldk-0-2-2-transcript"><em>LDK 0.2.2</em></p>
<p>We move forward with LDK 0.2.2. Here, this is another main release that follows
up two releases from last week’s newsletter related to LDK as well. Here, the
main difference is the update of the feature flag for the splicing feature that
has moved to the production feature bit. And we will cover this more in the
Notable code and documentation changes, because this is a PR of this week. But
there’s also other issues, such as when a restart happens, there could be an
operation that is left hanging and the channel manager doesn’t receive the
asynchronous confirmation that an operation was completed, followed usually
through the follow-up of a block connection. And so, yeah, just a few fixes
around a few synchronization events.</p>
<p id="hwi-3-2-0-transcript"><em>HWI 3.2.0</em></p>
<p>We follow up with Hardware Wallet Interface (HWI) 3.2.0. This is a release that
includes support for new hardware wallets, such as Jade Plus, BitBox02 Nova. It
also adds support for testnet4, native PSBT signing for the Blockstream Jade
hardware wallet. And finally, MuSig2 PSBT fields are added. And there’s also a
notable code change related to MuSig2 support in an HWI that we will cover more
in detail in a little while. Yes, please, Murch?</p>
<p><strong>Mark Erhardt</strong>: Maybe for context, the Bitcoin HWI is a package, a library
that is shipped by Bitcoin Core contributors. And it’s, for example, used by
Bitcoin Core to interface with a number of different hardware wallets. But I
think it’s now also used by other software projects for their interfacing with
hardware wallets. So, when hardware wallets get added here, that generally
means that these hardware wallets can be used by a number of different software
projects, software wallets now as signing devices.</p>
<p><strong>Gustavo Flores Echaiz</strong>: That’s exactly right. Thank you, Murch. So, for
example, Wasabi Wallet is an example of a wallet that will use HWI for
integrating with different hardware wallets.</p>
<p id="bitcoin-inquisition-29-2-transcript"><em>Bitcoin Inquisition 29.2</em></p>
<p>So, the final release is Bitcoin Inquisition 29.2, which is based on the second
RC of 29.3 Bitcoin Core. The main difference with the previous version of
Bitcoin Inquisition is that it implements the BIP54 proposal and disables
testnet4. And also, this newsletter includes a notable change that covers the
implementation of BIP54 in Bitcoin Inquisition 29.2. Yes, Murch?</p>
<p><strong>Mark Erhardt</strong>: For context, Bitcoin Inquisition is meant as the tool for
experimenting with proposed soft forks. So, it has a bunch of experimental soft
fork support, and it runs on the signet, on the main signet that is run by some
Bitcoin Core contributors. So, disabling testnet4 might sound scary for a
moment until you think about Inquisition is only meant to run with signet. So,
obviously testnet4 does not support these experimental soft forks and mainnet
certainly doesn’t either. So, Inquisition is not supposed to work with
testnet4. It was an oversight that it did, and it just basically will say, “No,
this is signet software, don’t use me with testnet4”, is the background here.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Thank you, Murch. Yeah, so mainnet and testnet3 were
already disabled, so this is just testnet4 being disabled in addition to other
networks that were disabled that that are supposed to be disabled. And also,
BIP54 is the new edition of this release, but Bitcoin Inquisition from previous
releases includes proposals such as BIP118, ANYPREVOUT (APO), BIP119,
CHECKTEMPLATEVERIFY (CTV), and other similar type of covenant or covenant-like
proposals.</p>
<p id="bitcoin-core-32420-transcript"><em>Bitcoin Core #32420</em></p>
<p>We move forward with the Notable code and documentation changes. This week we
have about 12 different PRs to cover. The first one, Bitcoin Core #32420,
updates the Mining IPC interface, which we have covered many times on the
newsletter, that allows external Stratum v2 client software to connect to
Bitcoin Core to interface with Bitcoin Core for external block template
creation. So, here, what is done is that Bitcoin Core will stop including a
dummy extraNonce in the coinbase scriptSig when interfacing with external
Stratum v2 clients through the Mining IPC interface. So, a new option is added
so that any RPC or interface in Bitcoin Core can choose to include this dummy
extraNonce or not. And the IPC codepath obviously sets that as false to not
include it.</p>
<p>So, basically, what does this all mean? The scriptSig of the coinbase, it has
basically two rules related to it. It must be between 2 and 100 bytes. And
since BIP34, it must also start with a push of the block height. The dummy
extraNonce is included usually for internal usage, such as the internal miner
unit tests, they will use that dummy extraNonce. But it was never shipped
outside of Bitcoin Core. So, for example, when a real miner used
getblocktemplate, getblocktemplate RPC would exclude the coinbase entirely
because the miners would build their own coinbase. So, this was mostly an
internal tooling for internal mining and related tests. So, when the Mining IPC
interface was added and implemented, this was basically overlooked and the dummy
extraNonce was shipped to external Stratum v2 clients, and they would then have
to either strip it or simply ignore it.</p>
<p>So, this PR basically adapts to the new reality where there’s now a Mining IPC
interface. So, it stops including a dummy extraNonce, which use case was pretty
much only internal. And there’s also a security reason behind this change.
It’s that if an external mining software would strip or ignore the scriptSig
entirely or strip the dummy extraNonce from the scriptSig, if a future soft fork
happened that required additional commitments in the scriptSig, well, the
external mining software that was used to simply ignoring it could just
accidentally break consensus, right? So, this is also the rationale behind this
change. Any extra thoughts, Murch?</p>
<p><strong>Mark Erhardt</strong>: Yeah, I wanted to talk a little bit about the scriptSig field
of the coinbase. So, coinbase inputs are special in the sense that they do not
commit to a specific UTXO that they’re spending. All inputs on Bitcoin
transactions usually tell us what input they are referring to for the spend.
But coinbase transactions obviously pay out the mining reward, so they do not
spend a UTXO. They still have a previous, like, an outpoint that they commit
to, but it’s a fixed value. So, they always fill out the previous txid and the
output counter on that with specific values. And then, the field afterwards,
which you call a scriptSig, which would be the input script for other inputs, is
actually the coinbase field. And the coinbase field here is special because it
has special requirements. As you said, it has to be between 2 and 100 bytes.
It has to start since, was it BIP34, with the height? And, yeah, so the
coinbase field is what would be the input script or scriptSig for other inputs.
And, yeah, coinbase inputs are special. Coinbase transactions also can only
have a single transaction input, which also is unusual.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Thank you, Murch. And just to add on top of that,
well, the extraNonce is what allows a minor to add additional nonce values.</p>
<p><strong>Mark Erhardt</strong>: Yeah, and to add to that, the extraNonce is not a special
field. It’s basically just using the coinbase field after the height to put
arbitrary other content. And by changing a single byte in the coinbase
transaction, obviously you change the merkle root and by changing – wait a
second. Yes, you change the merkle route. I was confused for a moment because
the coinbase transaction is obviously ignored for the segwit commitment in the
merkle tree for the segwit transactions. But in the regular merkle root, the
coinbase contributes of course, so that changes the header of the block that
you’re trying to create, and therefore gives you a new sequence of nonces that
you can iterate over or time-roll on or version-roll on, or whatever you want to
do. So, changing a single byte in the coinbase transaction gives you new block
headers to work with and that’s why it’s used as an extraNonce. Once the nonces
are exhausted, you can change the coinbase transaction to start over with the
regular nonces.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Right, and just to bring back to the PR after that
great explanation, it’s that this dummy extraNonce is mostly useful for internal
mining or testing, because miners will simply create their own coinbase
transaction with their desired extraNonce.</p>
<p id="core-lightning-8772-transcript"><em>Core Lightning #8772</em></p>
<p>So, we move forward with Core Lightning #8772. This is a fairly simple one.
Here, Core Lightning (CLN) removes full support for the legacy onion payment
format, which had a fixed length. This was very early days in Lightning. It
was completely removed from Bitcoin Core, from CLN and the BOLTs specification
in 2022, but it was brought back to CLN in v24.05 after it had found that some
older versions of LND were still producing these legacy onion payment formats.
So, it added a sort of translation layer to translate the legacy format to the
new variable length format. However, this is no longer the case since LND
v18.3, so support is no longer needed. Yes, Murch?</p>
<p><strong>Mark Erhardt</strong>: Just to clarify, you said it removes full support or do you
mean it fully removes support? Like, it removes all support?</p>
<p><strong>Gustavo Flores Echaiz</strong>: Yeah, it removes all support. Thank you for making
me clarify that. Yes, so it basically removes this translation layer that it
had added after. It’s no longer needed because LND new versions simply don’t
produce it anymore.</p>
<p id="lnd-10507-transcript"><em>LND #10507</em></p>
<p>So, this follows up with a PR on LND #10507. So, here, a new boolean field is
added to the GetInfo RPC response. So, there was already another boolean field
called synced_to_chain. So, what are the differences between these two boolean
fields and what is the necessity of the new one? Basically, the new
wallet_synced field will indicate whether a wallet has finished up catching on
the current chain tip. So, if you simply want to know if your wallet has caught
up to synchronizing to the blockchain, you can use that field to know just that
precisely.</p>
<p>The other field, synced_to_chain, would consider this, but would only turn true
if not only you had fully synced to the current chain tip, but your channel
graph router, which validates channel announcements, had also completed its job,
and another component called the blockbeat dispatcher, which is a subsystem that
coordinates block-driven events internally with different internal parts of LND,
that would also have to be completed or synced before returning true. So, this
new field allows you to simply know your status with blockchain synchronization,
and not worry about full synchronization or up-to-date work from other
components.</p>
<p><strong>Mark Erhardt</strong>: So, basically that would tell you when you’re up-to-date with
your own channels and your onchain payments even before you are up-to-date with
the channel graph.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Exactly.</p>
<p><strong>Mark Erhardt</strong>: Cool. All right.</p>
<p id="ldk-4387-transcript"><em>LDK #4387</em></p>
<p><strong>Gustavo Flores Echaiz</strong>: We move forward. We now have four different LDK PRs
to cover. So, the first one, LDK #4387. Here, like I was mentioning in the
Release section, because this is part of the new LDK release, the splicing
feature flag is changed from the provisional bit 155 to the production bit 63.
So, why did LDK use bit 155? Because it saw that Eclair also uses it and it
just went along with the same feature flag bit as Eclair to be fully compatible.
However, later, the LDK team realized that Eclair uses a custom Phoenix-specific
splicing implementation that predates the current splicing specification that is
in draft status, right? So, the Eclair team is not going to update or hasn’t
updated their splicing implementation until the splicing specification is merged
and leaves draft status. Until then, they remain with their custom
implementation. So, the LDK team didn’t know this and they had tried to be with
the same feature flag bit as Eclair, but later realized that when trying to
attempt a splice between LDK and Eclair, this would lead to, first of all,
deserialization failures, and then reconnections that would never lead to a
successful splice.</p>
<p>So, now the LDK team says, “We’re just going to point to the production bit,
because we’re basically implementing the draft specification that will probably
get merged over the next few weeks”. Yes, Murch?</p>
<p><strong>Mark Erhardt</strong>: Do you know whether this was in the released version already
of LDK, or is this on the development branch?</p>
<p><strong>Gustavo Flores Echaiz</strong>: That’s a very good question. And, yes, this was in
the released version.</p>
<p><strong>Mark Erhardt</strong>: But just a bug fix, not just a fix to the development? Okay.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Exactly. Yes, so this is why the version with this
fix is released, because it was already released.</p>
<p id="ldk-4355-transcript"><em>LDK #4355</em></p>
<p>So, the next one is a new feature added on LDK #4355, which basically adds
support for asynchronous signing of commitment signatures exchanged during
either splicing or dual-funded channel negotiations. So, the way it works is
that when using an asynchronous signer, when receiving a call to sign the
commitment, it will immediately return; and later, the asynchronous signer will
call back once its signature is ready. So, this is mostly ready for splicing.
So, for example, HSMs could be now used for signing, splicing, commitment
signatures in LDKs. For dual-funded channel negotiations, this is simply the
foundation, but some more work is required for adding full support to
asynchronous signers.</p>
<p id="ldk-4354-transcript"><em>LDK #4354</em></p>
<p>The next one is a very simple one as well, LDK #4354. This one is something
that was missed probably by the LDK team, or was long due. It’s making channels
with anchor outputs the default in LDK. The way they do this is they’ve got to
put the config option of negotiating channels by default, which means that
automatic channel acceptance is removed, because all inbound channel requests
before being accepted, the wallet has to ensure it has enough onchain funds to
cover fees in the event of a foreclosure. So, this simple change on two config
options was necessary to simply make channels with anchor outputs the default in
LDK.</p>
<p><strong>Mark Erhardt</strong>: So, the difference here is, of course, that with regular
channels, the side that opened the channel is always on the hook for the fee for
closing. And with anchor channels, the party that closes uses their anchor and
brings the fees in the anchor output. So, it’s a CPFP construction, and that
means you need to have additional funds available in order to be able to close
the channel unilaterally.</p>
<p id="ldk-4303-transcript"><em>LDK #4303</em></p>
<p><strong>Gustavo Flores Echaiz</strong>: Thank you for that extra context, Murch. And the
final one of the LDK ones, LDK #4303, this is not a released. So, this is a bug
fix on a branch that was unreleased. So, here, two bugs were fixed where an
HTLC (Hash Time Locked Contract) could be double-forwarded after your channel
manager restarts or your LDK node restarts. So, basically, in one case, you had
received an HTLC and you were going to forward it, but on your outbound channel,
you were waiting for something to clear for that channel to be ready for you to
forward the HTLC. But somehow, your channel manager or your LDK node restarted.
So, on restart, LDK would miss that the HTLC was in the internal queue, and it
would simply create another HTLC and dispatch both at the same time.</p>
<p>In the other scenario, the HTLC had already been forwarded, settled, and had
been removed from, let’s say, the internal logging, but the inbound side still
had a resolution for it. So, you would restart before it would fully resolve at
that level. So, on restart, it would dispatch another HTLC. And this led to
some potential loss of funds. However, this was never released, it never
shipped. So, the bug fix came right on time.</p>
<p><strong>Mark Erhardt</strong>: Yeah, the problem here would be, of course, if you create the
same HTLC twice, you’re essentially paying the recipient twice for what they’re
forwarding. So, they make one full HTLC more on the forward, and with the
recreating an already settled output, the other side already has the secret, so
they can simply take the output immediately. And neither of the two is
intended.</p>
<p id="hwi-784-transcript"><em>HWI #784</em></p>
<p><strong>Gustavo Flores Echaiz</strong>: Thank you for that extra explanation. The follow up
is HWI #784. This is something we discussed briefly on the release notes. But
basically, PSBT serialization and their serialization support is added for
MuSig2 fields, including public keys, public nonces, partial signatures. So,
basically, this is HWI getting prepared for implementing MuSig2 signing on
hardware wallets. Basically, this is a PR from the HWI repo, #784, where
serialization and deserialization of MuSig2 fields is added, PSBT support for
that is added, which is basically a preparation for signing MuSig2 transactions
by hardware wallets all specified in BIP327. So, probably a next version of HWI
will move forward with full MuSig2 support.</p>
<p><strong>Mark Erhardt</strong>: So, the problem here is, of course, when you’re creating a
MuSig2, you need additional information in order to know how the signatures are
being aggregated. And for this construction, you need more information then was
included in the regular PSBT setup. So, this is basically a necessary step for
hardware signers to be able to sign MuSig2 outputs.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Precisely. Give me just a second. Okay.</p>
<p><strong>Mark Erhardt</strong>: I can do the BIPs if you want.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Yeah, definitely. I think it would be very valuable
if you do the BIPs, please.</p>
<p id="bips-2092-transcript"><em>BIPs #2092</em></p>
<p><strong>Mark Erhardt</strong>: All right. BIPs #2092 is an update to BIP434, which we just
introduced recently, which is the feature message to negotiate between nodes
what features you want to use and maybe what versions of those features you want
to use. So, when we introduced BIP324, the P2P v2 encrypted P2P messages, there
is a message ID system there. There’s long and short messages, and this just
adds the message ID for the BIP434 feature message. It also introduces, in
BIP324, an auxiliary file where these message IDs are stored, because it’s not
really part of BIP324, so we decided not to put it in there. But it’s something
that other BIPs might want to add to when they designate certain message IDs.
So, it’s a separate file in BIP324’s auxiliary files. If you’re looking to
reserve any message IDs, check there that you’re not double-booking anything.
Did I miss anything?</p>
<p><strong>Gustavo Flores Echaiz</strong>: No, that’s perfect.</p>
<p id="bips-2004-transcript"><em>BIPs #2004</em></p>
<p><strong>Mark Erhardt</strong>: Okay. The BIPs PR #2004 adds Chain Code Delegation as BIP89.
BIP89 is a newly-published BIP that it’s basically a way of keeping your
transactions more private from a collaborative custody provider. So, when you
usually have collaborative custody, where your provider has some of the keys and
you have some of the keys, and they co-sign every transaction for you, they
would know about all of your wallet activity because you share your output
scripts with them, and they can see when you get paid and when you pay, even if
you construct the transaction completely on your end with your set of keys.
With the Chain Code Delegation BIP, the authors, Jurvis and Jesse, introduce a
method where you take all of the responsibility of tracking the funds, and you
can get the co-signing of the custodian only when you want it, and you only
reveal the transactions where they co-sign, and they only learn about the
transactions they participate in. And they do this by not knowing the chain
code, which is how you derive from the main secret all of the other keys in the
extended public key chain.</p>
<p>So, you, as the customer of the custody service, know the derivation path, and
you basically just tell the custodian, “Here, I want to make this transaction.
Here’s my proof that it’s me and that it fits the policy per which I’m allowed
to spend this amount”, or whatever. And then, the custodian gets the derivation
path from me to sign.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Yeah, I just want to add, well, first of all, this is
a fascinating topic, in my opinion, and a great proposal. But you can check out
Newsletter #364 and listen to the related podcast that came with it for extra
context. This was heavily discussed there. But also, there’s a blind mode for
that. I don’t know how secure it is. I think it’s not as secure as the
non-blinded signing mode. But in the blinded signing mode, the delegator or the
signer learns nothing, neither the message, neither the public key. It’s only
provided a blinded challenge and it signs it and that’s it.</p>
<p><strong>Mark Erhardt</strong>: I think that one is more just future work. So, the actual
proposal does not fully specify the blinded mode, but I think Jesse basically
outlines how it could be implemented if people wanted to work on it. But people
should correct me underneath this tweet if I’m wrong about that one.</p>
<p id="bips-2017-transcript"><em>BIPs #2017</em></p>
<p>All right. Third PR to the BIPs repository. This is PR #2017 to the BIPs
repository, and this publishes BIP110. If you’ve been on Twitter in the last
three months, I think you’ve seen mention of BIP110. This is also known as
Reduced Data Temporary Softfork (RDTS), a proposal to introduce seven new
consensus rules to forbid some types of transactions that some people think
shouldn’t be happening. BIP is written up complete enough to be published, and,
yeah, it was published now. I should say, it is somewhat controversial, because
introducing seven new consensus rules that, for example, forbid the use of OP_IF
and IP_NOTIF in tapscript, limiting the height of tapscript trees, and also
limiting all push opcodes to only 256 bytes may cause people to have their funds
frozen. The authors of the BIP have addressed that to some degree. They do not
apply these rules for any UTXOs that exist before activation, but only on new
UTXOs that are created after activation of this PR.</p>
<p>So, the soft fork is supposed to be active for one year once it activates. It
is also a little controversial per its activation method. It reduced the
signaling threshold to 55%, and it has mandatory activation in September after
mandatory signaling in August. So, any nodes that have upgraded to RDTS, to the
activation client for BIP110, will start forcing every block to signal for
activation on this proposal in August. So, if this is not followed or supported
by a majority of the hashrate at this point, they will fork themselves off and
be on a stale chain tip or slower-moving chain tip that does not follow the rest
of the network for not signaling readiness. For more on this, just look at
Twitter for three minutes. There’s everybody bashing in each other’s head on it
for the past few weeks. Just to be clear, I did review this, I did publish
this, I still think it’s a terrible idea, and I don’t think it’s a problem for
me saying so.</p>
<p><strong>Gustavo Flores Echaiz</strong>: No, absolutely not. I think it’s very, very just
rational to say that. Do you know if this has replay protection? Let’s say in
the case of a fork, do you know how protected a user would be from
double-spending or issues like that?</p>
<p><strong>Mark Erhardt</strong>: It does not have replay protection. So, all the transactions
that are accepted by BIP110 will be valid on either chain tip. And if you spend
a regular transaction, it would flow on both of these. So, with previous soft
forks, this was a big concern before Bcash split off. The Bcash developers
finally, in the last hours, literally I think in the last two days or so before
the proposal, finally changed the transaction format to introduce replay
protection when they realized that they didn’t have majority support. And in
this case, so some of the concerns are around reorgs that if this proposal had
any a reasonable amount of support, there probably would be at least a few reorg
blocks. But then also, if the heights diverge drastically, it might be possible
for Lightning channels to be resolved differently on the two chain tips,
especially if you’re running a Lightning node and using a BIP110 node as the
source of truth on this. This may open you up to some loss-of-funds situations.
And, yeah, so no replay protection.</p>
<p>If you do want to spend your funds separately on these two chains, you can wait
until there’s some block rewards that have been distributed in the network. Any
funds spent from a block that can only exist in one of the two chains will
spawn, like if it’s spent, all of the outputs on that transaction can also only
exist on that chain. And that sort of can infect the whole network. So, if
there’s any outputs that only exist on that chain, anything that is spent in
transactions with those, or spent from outputs that were created from those,
will also only be able to exist on that chain. And that way, funds can be split
eventually. The alternative is sending funds to yourself on both chains until
you manage to send them to two different addresses. So, if you, for example,
have very different feerates on the two networks, you could send it first on the
network with the low feerate. Then, once it’s flowed, you can send another
transaction on the other chain tip with a higher feerate, sending it to a
different address. And then, you’ve also split your funds successfully.</p>
<p>Obviously, if a reorg happened on one of those two chains, this could be
resolved in the other direction. So, you have to be careful that this gets a
few confirmations. But once you’ve split your funds, you can use that UTXO that
only exists on one chain to create transactions that are only valid on one
chain. And that way, you can split all of your funds and then you can dump
whatever side you want, for example, or create Lightning channels that only
exist on one of the two sides. There’s a lot of misinformation around this
being inevitable to succeed just because it is a soft fork. And I want to be
very clear that soft forks are not inevitable. A soft fork that is enforced by
a small minority of the network, especially a small minority of the hashrate and
a small number of nodes, and especially a small part of the economic activity of
the network, cannot enforce a soft fork. It will stall on a shorter chain that
has less PoW. The rest of the network will simply continue to follow the most
worked chain and pull away. So, don’t believe everything you read on the
internet.</p>
<p id="bitcoin-inquisition-99-transcript"><em>Bitcoin Inquisition #99</em></p>
<p><strong>Gustavo Flores Echaiz</strong>: Thank you, Murch. That was very well needed, I
believe. So, now we just have a final PR to cover on the newsletter. This is
the Bitcoin Inquisition PR #99. The implementation of the BIP54 consensus
cleanup soft fork is added on Bitcoin Inquisition and on signet. So, we
discussed many times this proposal. It was merged, I believe, only a few weeks
ago, like last month, and also we had the BIP author, Antoine Poinsot, on this
show on the last episode, #391, because he basically talked about addressing
remaining points on BIP54. So, I don’t believe those points have already been
addressed. I believe this Bitcoin Inquisition merges the BIP as is, but there
could still be some changes to the BIP proposal. Is that accurate?</p>
<p><strong>Mark Erhardt</strong>: No, I think the addressing outstanding points was mostly
discussing the concerns that were brought up, and I think neither of the two has
actually changed the proposal. So, the two points were specifically whether or
not the nLockTime field on coinbase transactions has been described as a
valuable extra nonce space for miners. And we discussed the validity or the
saliency of that claim and rejected it basically on noticing that it saves you,
like, a couple of hashes on the coinbase itself. But there is a number of
different things that you can do on the block header itself. Or, if you’re
updating the extra nonce or any other field on the coinbase, it’s like 1 more, 2
more hashes on the coinbase transaction to get to this point. It’s probably not
something that people would be getting super-excited about. It’s not used right
now. And forbidding it is a level playing field. Right now, it’s not being
used. If we forbid it from being used in the future, it doesn’t hurt anyone
specifically.</p>
<p>The other one was whether or not only forbidding 64-byte transactions creates a
consensus scene, where it’s weird that 63-byte transactions are allowed and
65-byte transactions are allowed, but 64-byte transactions are not allowed.
This is specifically in reference of the stripped size of transactions, so
transactions without witness data, but I really don’t see it being a bigger
concern that smaller transactions might be allowed and only one specific size
not being allowed. And even so, if we did want to also forbid 63-byte
transactions, and I think the smallest possible thing is 62-byte transactions.
Yeah, 41 bytes for the input, 10 bytes for the header, 1 byte – sorry, 60 bytes
might be possible, but whatever. So, I don’t share that concern. And Antoine
looked into these and rejected these, so I don’t think the BIP actually changed.</p>
<p>BIP54, the consensus cleanup as is, is now on signet and I’m looking forward to
seeing the PR to Bitcoin Core soon. I think that’ll get a little more review
and hopefully move the proposal forward. I think in light of other soft forks
currently being proposed, BIP54 uses a very deliberate and different approach.
This has been two years of research. These are rules that are engineered to
have minimal impact on any users, other than sweeping changes that definitely
will disenfranchise established protocols and wallet constructions. So, yeah,
my money is on BIP54 activating earlier.</p>
<p><strong>Gustavo Flores Echaiz</strong>: Makes sense. Thank you so much, Murch. Well, that
completes the PR section and the newsletter. Yes, Murch?</p>
<p><strong>Mark Erhardt</strong>: For ‘activating’ meaning adopted by the whole network, not
just being enforced by a handful of nodes on the network. Yes, this is the PR
section. Thank you, Gustavo, for preparing that and joining me on this Optech
Newsletter. Thank you to our guests, Oleksandr and Sebastian, for talking us
through the concern around paying silent payments recipients too often, and
BLISK, the boolean circuit logic integrated into the single key, which seems to
allow some very interesting constructions that also look like a single-sig P2TR
output. Unfortunately, who knows how long we can use them with quantum coming
any century now. So, yeah. Hear you next week, Gustavo?</p>
<p><strong>Gustavo Flores Echaiz</strong>: Yes, thank you much.</p>
<p><strong>Mark Erhardt</strong>: All right, that’s it.</p>Bitcoin OptechMark “Murch” Erhardt and Gustavo Flores Echaiz are joined by Sebastian Falbesoner and Oleksandr Kurbatov to discuss Newsletter #392.Bitcoin Optech Newsletter #3922026-02-13T00:00:00+00:002026-02-13T00:00:00+00:00https://bitcoinops.org/en/newsletters/2026/02/2026-02-13-newsletter<p>This week’s newsletter summarizes discussion of improving worst-case silent
payment scanning performance and describes an idea for enabling many spending
conditions in a single key. Also included are our regular sections with announcements
of new releases and release candidates and descriptions of notable changes to
popular Bitcoin infrastructure software.</p>
<h2 id="news">News</h2>
<ul>
<li id="proposal-to-limit-the-number-of-per-group-silent-payment-recipients" class="anchor-list">
<p><a href="#proposal-to-limit-the-number-of-per-group-silent-payment-recipients" class="anchor-list-link">●</a> <strong>Proposal to limit the number of per-group silent payment recipients</strong>: Sebastian
Falbesoner <a href="https://groups.google.com/g/bitcoindev/c/tgcAQVqvzVg">posted</a> to the Bitcoin-Dev mailing list the discovery and
mitigation of a theoretical attack on <a href="/en/topics/silent-payments/">silent
payment</a> recipients. The attack occurs when an adversary
constructs a transaction with a large number of taproot outputs (23255 max outputs per
block according to current consensus rules) that all target the same entity.
If there were no limit on group size, it would take several minutes
to process, rather than tens of seconds.</p>
<p>This motivated a mitigation to add a new parameter, <code class="language-plaintext highlighter-rouge">K_max</code>, that limits the
number of per-group recipients within a single transaction. In theory, this
change would not be backward-compatible, but in practice, none of the
existing silent payment wallets should be affected
for a sufficiently high <code class="language-plaintext highlighter-rouge">K_max</code>. Falbesoner is proposing <code class="language-plaintext highlighter-rouge">K_max=1000</code>.</p>
<p>Falbesoner is seeking feedback or concerns about the proposed restriction. He
also notes that most silent payment wallet developers have been notified and
are aware of the issue. <a href="/en/podcast/2026/02/17/#proposal-to-limit-the-number-of-per-group-silent-payment-recipients"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="blisk-boolean-circuit-logic-integrated-into-the-single-key" class="anchor-list">
<p><a href="#blisk-boolean-circuit-logic-integrated-into-the-single-key" class="anchor-list-link">●</a> <strong>BLISK, Boolean circuit Logic Integrated into the Single Key</strong>: Oleksandr
Kurbatov <a href="https://delvingbitcoin.org/t/blisk-boolean-circuit-logic-integrated-into-the-single-key/2217">posted</a> to Delving Bitcoin about BLISK, a protocol
designed to express complex authorization policies using boolean logic.
BLISK tries to address the limitations of current spending policies. For example,
protocols like <a href="/en/topics/musig/">MuSig2</a>, though efficient and privacy-preserving,
can only express cardinality (k-of-n) but cannot identify “who” can spend.</p>
<p>BLISK creates a simple AND/OR boolean circuit, mapping logical gates to
well-known cryptographic techniques. In particular, AND gates are obtained by
applying an n-of-n multisignature setup, in which each participant must contribute a
valid signature. On the other end, OR gates are obtained by leveraging key agreement
protocols, such as <a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>, in which any participant can derive a shared
secret using their private key and the other participant’s public key. It also applies
a <a href="https://en.wikipedia.org/wiki/Non-interactive_zero-knowledge_proof">Non-interactive Zero Knowledge proof</a> to make circuit resolution
verifiable and to prevent cheating.
BLISK resolves the circuit to a single signature verification key. This means
that only a single <a href="/en/topics/schnorr-signatures/">Schnorr</a> signature must be verified
against one public key.</p>
<p>Another important advantage of BLISK with respect to other approaches is
eliminating the need to generate a fresh key pair. In fact, it allows connecting an
existing key to the specific signature instance.</p>
<p>Kurbatov provided a <a href="https://github.com/zero-art-rs/blisk">proof-of-concept</a> for the protocol, although he stated
that the framework has not reached production maturity yet. <a href="/en/podcast/2026/02/17/#blisk-boolean-circuit-logic-integrated-into-the-single-key"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="releases-and-release-candidates">Releases and release candidates</h2>
<p><em>New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.</em></p>
<ul>
<li id="bitcoin-core-29-3" class="anchor-list">
<p><a href="#bitcoin-core-29-3" class="anchor-list-link">●</a> <a href="https://bitcoincore.org/bin/bitcoin-core-29.3/">Bitcoin Core 29.3</a> is a maintenance release for the previous major
release series that includes several wallet migration fixes (see
Newsletter <a href="/en/newsletters/2026/01/09/#bitcoin-core-wallet-migration-bug">#387</a>), a per-input sighash midstate cache
that reduces the impact of quadratic sighashing in legacy scripts (see
Newsletter <a href="/en/newsletters/2025/08/15/#bitcoin-core-32473">#367</a>), and removal of peer discouragement
for consensus-invalid transactions (see Newsletter <a href="/en/newsletters/2025/08/15/#bitcoin-core-33050">#367</a>). See the <a href="https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-29.3.md">release notes</a> for all details. <a href="/en/podcast/2026/02/17/#bitcoin-core-29-3"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-0-2-2" class="anchor-list">
<p><a href="#ldk-0-2-2" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/releases/tag/v0.2.2">LDK 0.2.2</a> is a maintenance release of this library for building
LN-enabled applications. It updates the <code class="language-plaintext highlighter-rouge">SplicePrototype</code> feature flag
to the production feature bit (63), fixes an issue where async
<code class="language-plaintext highlighter-rouge">ChannelMonitorUpdate</code> persistence operations could hang after restarts
and lead to force-closures, and fixes a debug assertion failure that
occurred when receiving invalid splicing messages from a peer. <a href="/en/podcast/2026/02/17/#ldk-0-2-2"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="hwi-3-2-0" class="anchor-list">
<p><a href="#hwi-3-2-0" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin-core/HWI/releases/tag/3.2.0">HWI 3.2.0</a> is a release of this package providing a common interface
to multiple hardware signing devices. The new release adds
support for the Jade Plus and BitBox02 Nova devices, <a href="/en/topics/testnet/">testnet4</a>, native <a href="/en/topics/psbt/">PSBT</a> signing for Jade, and <a href="/en/topics/musig/">MuSig2</a> PSBT fields as specified in <a href="https://github.com/bitcoin/bips/blob/master/bip-0373.mediawiki">BIP373</a>. <a href="/en/podcast/2026/02/17/#hwi-3-2-0"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-inquisition-29-2" class="anchor-list">
<p><a href="#bitcoin-inquisition-29-2" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin-inquisition/bitcoin/releases/tag/v29.2-inq">Bitcoin Inquisition 29.2</a> is a release of this <a href="/en/topics/signet/">signet</a>
full node designed for experimenting with proposed soft forks and other
major protocol changes. Based on Bitcoin Core 29.3r2, this release
implements the <a href="https://github.com/bitcoin/bips/blob/master/bip-0054.md">BIP54</a> (<a href="/en/topics/consensus-cleanup-soft-fork/">consensus cleanup</a>)
proposal and disables <a href="/en/topics/testnet/">testnet4</a>. <a href="/en/podcast/2026/02/17/#bitcoin-inquisition-29-2"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>
<h2 id="notable-code-and-documentation-changes">Notable code and documentation changes</h2>
<p><em>Notable recent changes in <a href="https://github.com/bitcoin/bitcoin">Bitcoin Core</a>, <a href="https://github.com/ElementsProject/lightning">Core
Lightning</a>, <a href="https://github.com/ACINQ/eclair">Eclair</a>, <a href="https://github.com/lightningdevkit/rust-lightning">LDK</a>,
<a href="https://github.com/lightningnetwork/lnd/">LND</a>, <a href="https://github.com/bitcoin-core/secp256k1">libsecp256k1</a>, <a href="https://github.com/bitcoin-core/HWI">Hardware Wallet
Interface (HWI)</a>, <a href="https://github.com/rust-bitcoin/rust-bitcoin">Rust Bitcoin</a>, <a href="https://github.com/btcpayserver/btcpayserver/">BTCPay
Server</a>, <a href="https://github.com/bitcoindevkit/bdk">BDK</a>, <a href="https://github.com/bitcoin/bips/">Bitcoin Improvement
Proposals (BIPs)</a>, <a href="https://github.com/lightning/bolts">Lightning BOLTs</a>,
<a href="https://github.com/lightning/blips">Lightning BLIPs</a>, <a href="https://github.com/bitcoin-inquisition/bitcoin">Bitcoin Inquisition</a>, and <a href="https://github.com/bitcoin-inquisition/binana">BINANAs</a>.</em></p>
<ul>
<li id="bitcoin-core-32420" class="anchor-list">
<p><a href="#bitcoin-core-32420" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bitcoin/issues/32420">Bitcoin Core #32420</a> updates the Mining IPC interface (see
<a href="/en/newsletters/2024/07/05/#bitcoin-core-30200">Newsletter #310</a>) to stop including a dummy
<code class="language-plaintext highlighter-rouge">extraNonce</code> in the coinbase <code class="language-plaintext highlighter-rouge">scriptSig</code>. A new
<code class="language-plaintext highlighter-rouge">include_dummy_extranonce</code> option is added to <code class="language-plaintext highlighter-rouge">CreateNewBlock()</code>, and
the IPC codepath sets it to <code class="language-plaintext highlighter-rouge">false</code>. <a href="/en/topics/pooled-mining/">Stratum v2</a>
clients receive only the consensus-required <a href="https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki">BIP34</a> height in the
<code class="language-plaintext highlighter-rouge">scriptSig</code> and no longer need to strip or ignore the extra data. <a href="/en/podcast/2026/02/17/#bitcoin-core-32420"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="core-lightning-8772" class="anchor-list">
<p><a href="#core-lightning-8772" class="anchor-list-link">●</a> <a href="https://github.com/ElementsProject/lightning/issues/8772">Core Lightning #8772</a> removes support for the legacy onion payment
format. While CLN had stopped creating legacy onions in 2022 (see
<a href="/en/newsletters/2022/03/30/#c-lightning-5058">Newsletter #193</a>), it added a translation layer in
v24.05 to handle the few remaining legacy onions produced by older LND
versions. These have not been created since LND v0.18.3, so support is
no longer needed. The legacy format was removed from the BOLTs
specification in 2022 (see <a href="/en/newsletters/2022/10/05/#bolts-962">Newsletter #220</a>). <a href="/en/podcast/2026/02/17/#core-lightning-8772"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="lnd-10507" class="anchor-list">
<p><a href="#lnd-10507" class="anchor-list-link">●</a> <a href="https://github.com/lightningnetwork/lnd/issues/10507">LND #10507</a> adds a new <code class="language-plaintext highlighter-rouge">wallet_synced</code> boolean field to the
<code class="language-plaintext highlighter-rouge">GetInfo</code> RPC response, which indicates whether the wallet has finished
catching up to the current chain tip. Unlike the existing
<code class="language-plaintext highlighter-rouge">synced_to_chain</code> boolean field, this new field does not require the
channel graph router (which validates <a href="/en/topics/channel-announcements/">channel announcements</a>) or the blockbeat dispatcher (a subsystem that
coordinates block-driven events) to be synced before returning true. <a href="/en/podcast/2026/02/17/#lnd-10507"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4387" class="anchor-list">
<p><a href="#ldk-4387" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4387">LDK #4387</a> switches the <a href="/en/topics/splicing/">splicing</a> feature flag from
the provisional bit 155 to the production bit 63. LDK v0.2 used bit
155, which Eclair also uses for a custom, Phoenix-specific splice
implementation that predates and is incompatible with the current draft
specification. This caused Eclair nodes to attempt splices using their
protocol when connecting to LDK nodes, resulting in deserialization
failures and reconnections. <a href="/en/podcast/2026/02/17/#ldk-4387"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4355" class="anchor-list">
<p><a href="#ldk-4355" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4355">LDK #4355</a> adds support for async signing of commitment signatures
exchanged during <a href="/en/topics/splicing/">splicing</a> and <a href="/en/topics/dual-funding/">dual-funded</a> channel negotiations. When receiving
<code class="language-plaintext highlighter-rouge">EcdsaChannelSigner::sign_counterparty_commitment</code>, the async signer
immediately returns and calls back via
<code class="language-plaintext highlighter-rouge">ChannelManager::signer_unblocked</code> once the signature is ready.
Dual-funded channels still require additional work to fully support
async signing. <a href="/en/podcast/2026/02/17/#ldk-4355"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4354" class="anchor-list">
<p><a href="#ldk-4354" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4354">LDK #4354</a> makes channels with <a href="/en/topics/anchor-outputs/">anchor outputs</a>
the default by setting the config option of
<code class="language-plaintext highlighter-rouge">negotiate_anchors_zero_fee_htlc_tx</code> to true by default. Automatic
channel acceptance has been removed, so all inbound channel requests
must be manually accepted. This ensures that the wallet has enough
on-chain funds to cover fees in the event of a force close. <a href="/en/podcast/2026/02/17/#ldk-4354"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="ldk-4303" class="anchor-list">
<p><a href="#ldk-4303" class="anchor-list-link">●</a> <a href="https://github.com/lightningdevkit/rust-lightning/issues/4303">LDK #4303</a> fixes two bugs where <a href="/en/topics/htlc/">HTLCs</a> could be
double-forwarded after a <code class="language-plaintext highlighter-rouge">ChannelManager</code> restart: one where the
outbound HTLC was still in a holding cell (internal queue) but it was
missed, and another where it had already been forwarded, settled, and
removed from the outbound channel, but the inbound side’s holding cell
still had a resolution for it. This PR also prunes inbound HTLC onions
once they are irrevocably forwarded. <a href="/en/podcast/2026/02/17/#ldk-4303"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="hwi-784" class="anchor-list">
<p><a href="#hwi-784" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin-core/HWI/issues/784">HWI #784</a> adds <a href="/en/topics/psbt/">PSBT</a> serialization and deserialization
support for <a href="/en/topics/musig/">MuSig2</a> fields, including participant public
keys, public nonces, and partial signatures for both inputs and
outputs, as specified in <a href="https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki">BIP327</a>. <a href="/en/podcast/2026/02/17/#hwi-784"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-2092" class="anchor-list">
<p><a href="#bips-2092" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/2092">BIPs #2092</a> assigns a one-byte <a href="/en/topics/v2-p2p-transport/">v2 P2P transport</a> message type ID to the <code class="language-plaintext highlighter-rouge">feature</code> message from <a href="https://github.com/bitcoin/bips/blob/master/bip-0434.md">BIP434</a>,
and adds an auxiliary file to <a href="https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki">BIP324</a> tracking one-byte ID
assignments across BIPs to help developers avoid conflicts. The file
also records <a href="/en/topics/utreexo/">Utreexo</a>’s proposed assignments from
BIP183. <a href="/en/podcast/2026/02/17/#bips-2092"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-2004" class="anchor-list">
<p><a href="#bips-2004" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/2004">BIPs #2004</a> adds <a href="https://github.com/bitcoin/bips/blob/master/bip-0089.mediawiki">BIP89</a> for Chain Code Delegation (see
<a href="/en/newsletters/2025/07/25/#chain-code-withholding-for-multisig-scripts">Newsletter #364</a>), a collaborative custody
technique where a delegatee withholds <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP32</a> chain codes from a
delegator, sharing only enough information with the delegator to
produce signatures without learning which addresses received funds. <a href="/en/podcast/2026/02/17/#bips-2004"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bips-2017" class="anchor-list">
<p><a href="#bips-2017" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin/bips/issues/2017">BIPs #2017</a> adds <a href="https://github.com/bitcoin/bips/blob/master/bip-0110.mediawiki">BIP110</a>, which specifies the Reduced Data
Temporary Softfork (RDTS), a proposal to temporarily restrict
data-carrying transaction fields at the consensus level for
approximately one year. The rules would invalidate scriptPubKeys
exceeding 34 bytes (except OP_RETURN up to 83 bytes), pushdata and
witness stack elements exceeding 256 bytes, spending of undefined
witness versions, <a href="/en/topics/taproot/">taproot</a> annexes, control blocks
exceeding 257 bytes, <code class="language-plaintext highlighter-rouge">OP_SUCCESS</code> opcodes, and <code class="language-plaintext highlighter-rouge">OP_IF</code>/<code class="language-plaintext highlighter-rouge">OP_NOTIF</code> in
<a href="/en/topics/tapscript/">tapscripts</a>. Inputs spending UTXOs created before
activation are exempt. Activation uses a modified <a href="https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki">BIP9</a> deployment
with a reduced 55% miner signaling threshold and mandatory lock-in by
approximately September 2026. See <a href="/en/newsletters/2025/11/07/#temporary-soft-fork-to-reduce-data">Newsletter #379</a> for
earlier coverage of this proposal. <a href="/en/podcast/2026/02/17/#bips-2017"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
<li id="bitcoin-inquisition-99" class="anchor-list">
<p><a href="#bitcoin-inquisition-99" class="anchor-list-link">●</a> <a href="https://github.com/bitcoin-inquisition/bitcoin/issues/99">Bitcoin Inquisition #99</a> adds an implementation of the <a href="https://github.com/bitcoin/bips/blob/master/bip-0054.md">BIP54</a>
<a href="/en/topics/consensus-cleanup-soft-fork/">consensus cleanup</a> soft fork rules on
<a href="/en/topics/signet/">signet</a>. The four implemented mitigations are: limits on
the number of potentially executed legacy sigops per transaction,
prevention of timewarp attacks with a two-hour grace period (plus
prevention of negative difficulty adjustment intervals), mandatory
timelocking of coinbase transactions to the block height, and
invalidation of 64-byte transactions. <a href="/en/podcast/2026/02/17/#bitcoin-inquisition-99"><i class="fa fa-headphones" title="Listen to our discussion of this on the podcast"></i></a></p>
</li>
</ul>Bitcoin OptechThis week’s newsletter summarizes discussion of improving worst-case silent payment scanning performance and describes an idea for enabling many spending conditions in a single key. Also included are our regular sections with announcements of new releases and release candidates and descriptions of notable changes to popular Bitcoin infrastructure software.