This week’s newsletter summarizes the responsible disclosure of two
denial-of-service vulnerabilities affecting older versions of Eclair and
describes a proposal for synchronizing wallet labels between devices
through an untrusted store. Also included are our regular sections summarizing
proposals and discussion about changing Bitcoin’s consensus rules, announcing
new releases and release candidates, and describing notable changes to popular
Bitcoin infrastructure software.
● Disclosure of two DoS vulnerabilities in Eclair: Matt Morehouse
posted to Delving Bitcoin the responsible
disclosure of two denial-of-service (DoS)
vulnerabilities affecting Eclair v0.13.1 and earlier. Both were fixed in
Eclair v0.14.0, released in May, and users still running
an older version should upgrade. Each attack requires only a completed
BOLT8 handshake, not a channel.
The first vulnerability is in feature bit parsing. Eclair parsed the
feature bits in an init message one at a time, allocating several
objects per bit, so a single maximum-length init message allocated and
discarded about 300 MB of memory and occupied a parsing thread for up to
300 ms. In Morehouse’s tests, an attacker with a few dozen connections
repeating that message disconnected all of the node’s peers within a minute
and exhausted its memory within five. Morehouse found the bug with
smite, his LN fuzzer, using its most basic test, which sends
raw bytes as a single message and checks that the target still answers a
ping promptly. The fix was merged in March as part of Eclair #3264, a
refactoring of feature parsing that did not mention the vulnerability.
The second vulnerability is in gossip queries. BOLT7 removed the zlib
encoding for query_short_channel_ids messages in April 2022, and Eclair stopped
sending it the same month but continued to accept it. The zlib decompression
had no output limit, so a 64 kB message could inflate to 64 MB and about 17
million objects, and a flood of such messages took a node offline within
seconds. Morehouse found it after the first bug by using an LLM to search the
Eclair codebase for other places where a peer could impose far more work on
the node than it spends itself. The fix is Eclair #3263.
● Proposal for wallet label synchronization: Jakub posted
to the Bitcoin-Dev mailing list to gauge interest in standardizing
synchronization of wallet labels between wallets
through a shared, untrusted store before writing a specification. Although
BIP329 standardized a label export format (see Newsletter #215), moving labels between wallets that use the same
descriptor, such as a coordinator and a watch-only
wallet, remains a manual export and import cycle, so coin selection decisions
are made without the associated labels.
Under the proposal, wallets derive a storage location and encryption keys
from a canonical form of the descriptor, without any private keys, so
wallets sharing a descriptor find the same data with no configuration.
Unmodified BIP329 records travel inside an authenticated encryption
envelope. Each record is stored with the time it was written, so when two
wallets change the same label, the most recent change takes precedence.
Because BIP329 has no way to delete a label, a deletion is recorded as a
marker that removes the label from other wallets. Jakub proposes Nostr as
the reference transport, but the protocol only requires a service that can
store and return data. The Bitcoin Safe wallet already synchronizes labels
this way over Nostr. Jakub asked whether encryption keys should derive from
the descriptor, which lets a wallet restore its labels from the descriptor
alone but exposes them to anyone who has held the xpubs, or from a separate
secret. He also asked whether to use one shared keypair across devices or
per-device pairing, and how to define the canonical descriptor form.
Craig Raw replied that label synchronization should be part of a broader
inter-wallet communication specification, which should include other use cases
such as PSBTs, multisig setups, and payment confirmations.
He also pushed back on the use of Nostr as the reference transport protocol,
since exchange of financial data should optimize for privacy, rather than
censorship resistance, and noted that he is working on a BIP for canonical
output descriptors.
A monthly section summarizing proposals and discussion about changing
Bitcoin’s consensus rules.
● Continued discussion of PQC output types: Following last month’s
summary of Pieter Wuille’s Delving Bitcoin thread on
post-quantum output types, Antoine Riard
replied affirming that a P2TRv2 output
whose quantum-vulnerable spend paths can later be disabled only within that
output type is acceptable because users opt in by receiving to it, avoiding a
generic freeze of existing outputs. He prefers not to bundle CISA with that change, and suggested a later P2MR-based type
with a new witness style, plus optional leaf versions so some coins could
keep a secp256k1-secured path after others had been disabled.
Conduition
argued that even P2TRv2 is not a trivial
witness-version bump: wallets that actually use the post-quantum path still
need new standards for deriving PQ keys, replacing BIP32-style workflows.
Wuille replied that CISA is unlikely to move the
long tail of wallets whose users do not care about fees or PQ, and that
neither P2TRv2 nor P2MR is a categorically quantum-secure output type,
because both rely on someone deciding when to stop using secp256k1. P2MR lets
the owner decide, but Wuille believes address reuse and public key sharing
are too entrenched for most users to benefit.
Antoine Poinsot
agreed that P2TRv2 and CISA pull in opposite directions:
users who want CISA without expecting an early secp256k1 disablement may refuse
P2TRv2 or, worse, adopt it without a post-quantum spend path, undermining a
later secp256k1 disablement. He also noted that shipping them as separate
output types could leave
distinguishable footprints if both become widely used. Conduition and Wuille
continued to discuss whether P2MR’s protection is achievable in
practice, and Conduition proposed deploying both
output types and letting users choose.
● Block-wide signature aggregation via SNARKs: Conduition
posted to Delving Bitcoin a design sketch for
compressing many post-quantum signatures
in a block into a single SNARK (see also
Ethan Heilman’s earlier proposal and
Newsletter #412). Hash-based signatures are cheap to verify
but large; a witness discount large enough to make them fee-competitive
would grow archival storage into terabytes per year (see Newsletter
#417).
Conduition expects large mining pools to produce
the proofs themselves and argues that ordinary nodes should never run a
prover. His design uses a bespoke aggregation
circuit rather than a general-purpose virtual machine (VM), a single flat
proof rather than recursive proofs, and a SPHINCS
variant with WOTS+C rather than SLH-DSA. Verifying the variant takes the
same number of hash operations for every signature, whereas the number for
SLH-DSA depends on choices the signer makes, so a circuit for it would have
to be sized for the most expensive case. The smallest hash-based SNARK proofs
are typically 300-500 kB. To allay concerns about the soundness of the
proposed proof, he sketched out several mechanisms to recover or opt out
depending on future conditions. He argues against allowing both
raw signatures and a SNARK as valid block formats, which would let miners mine
while a proof is produced instead of mining empty blocks, because resource
limits would have to assume the worst case. A naive extrapolation from the
SHA256 benchmarks in Flock, a SNARK prover for hash circuits, suggested about
20 seconds to prove a 10,000-signature block on a 10-thread CPU, with hope of
reducing that below 10 seconds; Conduition noted that nobody has yet tested a
SPHINCS verifier circuit in Flock.
Jonas Nick pointed to work showing that a SNARK’s
random-oracle proof does not automatically cover recursive use of
the same SNARK. ZmnSCPxj warned that a DoS in
prover code used by miners could stall block production, and
suggested shipping the prover in Bitcoin Core so it gets review.
● Bounds on chain length with BIP54 time warp fixes: Pieter Wuille
posted to Delving Bitcoin a proof that the two
timestamp rules in the consensus cleanup
proposal (BIP54) suffice to bound how many blocks can be mined in a chain
of given work. The bound is machine-checked in Lean, so only the statement
being proven needs review. The first rule (classic time warp) requires
the first block of a retarget period to be no more than
7,200 seconds before the preceding block; the second (Murch–Zawy; see
Newsletter #316) requires the last block of a
period not to predate the first. Together they bound the long-term
block rate to about one block per 9 minutes 56 seconds, plus a
bounded number of extra blocks paid for with difficulty increases.
For a chain at height 966,270 the formula allows at most 1,012,794
blocks, about 3,300 times tighter than with neither rule. Omitting
either rule leaves a limit above 3.34 billion blocks. The longest
constructed chain Wuille reported is 1,007,326 blocks.
Wuille’s
motivation was Bitcoin Core’s headers presync DoS protection,
which could rely on the bound once BIP54 is buried. Zawy discussed alternative
formulations. Wuille later proved a complementary lower bound on the
work required to produce a chain of a given length in a given time.
● Comparing covenant proposals for vaults: Lillian Wang
posted to Delving Bitcoin and cross-posted to the Bitcoin-Dev mailing list a report
comparing simplified vault constructions using
presigned transactions, OP_CHECKTEMPLATEVERIFY (CTV), SIGHASH_ANYPREVOUT / SIGHASH_ANYPREVOUTANYSCRIPT (APO/APOAS),
OP_TXHASH, OP_CHECKCONTRACTVERIFY (CCV,
BIP443), and an OP_CAT-based Purrfect Vault.
The report concludes that CTV fits simple vaults with precomputed
outputs, CCV best supports partial withdrawals and choosing a
withdrawal address at trigger time, and TXHASH offers more
commitment flexibility at the cost of more designer responsibility.
APOAS and CAT may be more appealing if their broader non-vault
applications are also valued.
askii21m noted
that APOAS signatures can be combined across two deposits to the
same vault address in a single transaction that creates the expected
output only once, with the second deposit’s value going to fees (a half-spend), because APOAS commits to neither the input
count nor the input index, so never reusing a vault address is a
requirement rather than a recommendation.
● Depots for probabilistic Lightning channels: John Law
posted to Delving Bitcoin a protocol
in which an operator funds a single time-limited taproot output (a depot)
that can host Lightning channels for many thousands or millions of users.
Users buy those channels from the operator with a Lightning payment rather
than putting their own funds onchain. Those balances are typically too small
to be worth claiming onchain, so a depot replaces each user’s small guaranteed
claim with a chance at a large one of the same expected value, which bounds
how many claims can ever go onchain.
Each purchased channel is assigned a
secret guess, chosen by the user, between zero and a large prime (P), and has a 1/P chance of
being a “hit” after the depot expires. Before expiry, users are expected to
drain their channels in the depot by paying out over Lightning (potentially
to a later depot) and revealing their guesses to revoke those channels so
they cannot be hits. After expiry the operator reveals a target: a channel
is a hit if its guess matches. If no channel hits, the operator reclaims the
output. If exactly one channel hits, that user can force the depot onchain
and receive P times their offchain balance (so a 1/P chance of a P-times
payout has the same expected value as the user’s actual balance). If two or
more channels hit, the depot is burned, which prevents users from collecting more than the depot
holds.
According to Law, this keeps the onchain footprint to about 1 or 2
vbytes per user per year, and avoids a thundering herd of forced onchain
transactions because a depot resolves in a constant-size set of transactions
regardless of how many users it hosts. Security relies on griefer
penalization: a party that griefs (for example by refusing to cooperate in a
drain) must expect to lose a configured fraction of the damage it inflicts.
Depots require OP_CHECKSIGFROMSTACK and
OP_CHECKTEMPLATEVERIFY. They are more efficient with OP_PAIRCOMMIT
(BIP442), OP_MUL, and OP_MOD, but do not require them.
Anzus asked
what happens if a user misses expiry or loses a device. Law replied that unlike his timeout trees, the operator cannot roll a depot over without a user-provided
secret, that wallets can automate an early drain, and that recovery needs
depot parameters and channel state in addition to a seed.
New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.
● Bitcoin Core #29278 adds a -maxfeerate config option that caps the
feerate of wallet transactions at 0.10 BTC/kvB (10,000 sat/vB) by default.
Previously, the -maxtxfee option was documented as an absolute fee cap.
However, certain checks also interpreted the same amount as a fee per 1,000
vB (see Newsletter #54). The new option separates the feerate limit from the total fee limit and
applies to transaction creation, fee bumping, CPFP
and regular wallet broadcast.
● Bitcoin Core #35984 fixes a bug where PSBT signing could
produce a SIGHASH_SINGLE signature without a corresponding output. This
sighash type commits to the output at the same index as the input being
signed. If the corresponding output is missing, legacy signing produces a
signature over a constant hash (see Newsletter #207). This
signature can be reused to spend other UTXOs controlled by the same key,
provided the corresponding output remains missing. Bitcoin Core now leaves
such inputs unsigned for legacy and segwit v0, while still signing the PSBT’s
other inputs, extending a check already present in raw transaction signing.
● Bitcoin Core #35301 begins the BIP352 silent payments implementation by adding support for encoding and decoding
addresses, deriving taproot payment outputs from eligible
transaction inputs, and scanning transactions for payments to a recipient. It
also adds support for labels to distinguish payments to different derived
addresses and identify change. The implementation builds on libsecp256k1’s
silent-payments module (see Newsletter #415). However, this
PR does not yet enable sending or receiving silent payments through the
wallet’s RPCs or GUI.
● Bitcoin Core #36312 fixes a privacy leak in the experimental, opt-in
private transaction broadcasting feature (see Newsletter #388). Previously, discouraging a misbehaving peer could disconnect both regular and private broadcast
connections to the same address. A malicious peer could deliberately trigger
these disconnections to link a private broadcast connection to the node’s
regular connections, weakening transaction origin privacy. Now, misbehaving private broadcast peers are disconnected
without discouraging their addresses, and discouraging regular peers leaves
private broadcast connections to the same addresses intact.
● Bitcoin Core #36284 fixes a bug where the wallet could reject a payment
despite having enough eligible funds when partial-spend avoidance is enabled
via the -avoidpartialspends option (see Newsletter #6)
or the wallet’s avoid_reuse flag (see Newsletter #52). Partial-spend avoidance groups
together outputs paid to the same address during coin selection to reduce output linking. Previously, if a
group failed eligibility checks (e.g. the limit on unconfirmed ancestors),
its value was subtracted twice from the amount available for selection. Now,
each rejected group’s value is subtracted only once.
● Bitcoin Core #35752 fixes error handling when encrypting a wallet,
changing its encryption passphrase, or adding private keys. Previously, a
failed database write could cause a passphrase change to appear successful,
but only the old passphrase would work after reloading the wallet. The
encryption process could also report success despite missing required key
records or leaving plaintext private keys in the database, while a failed
database commit could terminate Bitcoin Core. Failed private-key insertions
could leave keys only in memory, causing them to disappear from the wallet
upon reloading. Now, the wallet checks database operations, rolls back failed
encryption updates, and only updates its in-memory keys after the
corresponding writes succeed, allowing failed operations to be retried. The
PR also prevents a failed passphrase change from leaving a previously locked
wallet unlocked and reports database or encryption failures separately from
incorrect passphrase errors.
● Bitcoin Core #35813 adds a listrawtransactions wallet RPC that can list
every transaction known to the wallet, returning one entry per transaction
with its raw transaction hex. The existing listtransactions RPC returns
accounting entries: a self-transfer to a receiving address can appear as both
a send and a receive, while a transfer entirely to change addresses can be
omitted. The count and skip parameters provide pagination, and verbose
adds decoded transaction details.
● BIPs #2276 and #2277 correct PSBT
finalization rules that could discard information needed for later signing or
transaction extraction. The first removes BIP376’s requirement to delete
PSBT_IN_WITNESS_UTXO when finalizing a silent-payment input (see Newsletter #401). Other
taproot inputs in the same transaction may still require
that spent output’s amount and script to compute their signatures. The second
updates BIP370 to retain previous output identifiers, sequence numbers,
and required locktimes after a PSBTv2 input is finalized.
Deleting these fields could invalidate the PSBT or alter the extracted
transaction. It also removes an erroneous BIP371 instruction to delete
output taproot derivation data during input finalization.
● LDK #4993 fixes a bug that could cause a wallet to spend reserved inputs
in a transaction conflicting with an unconfirmed splice.
Previously, if LDK rejected an RBF fee-bump contribution because
the channel had already been force-closed, it could instruct the wallet to
release inputs still needed by the original splice. Across successive
fee-bump attempts, the wallet could also receive duplicate release
instructions or keep reservations after they were no longer needed. Now, each
funding contribution records which inputs and outputs it inherited from
earlier attempts, so failure tells the wallet to release only that
contribution’s own reservations. The PR also adds error information and
reservation queries to help applications retry failed contributions safely.
● LND #11173 fixes a bug where an invalid or oversized channel range
response could stall the initial sync of channel announcements until the next scheduled attempt. LND limits responses
to a total of 100,000 short channel IDs (SCIDs) per query (see Newsletter
#417). Now, when another eligible peer is available, LND
immediately retries synchronization with it and temporarily excludes the
failed peer from selection. The existing connection to the failed peer remains
open.
● LND #11190 updates LND to reject BOLT11 invoices containing multiple
payment hash (p) fields, even when the hashes are identical. Previously,
LND used the first supported payment hash and ignored the rest, as
recommended by the BOLT11 spec. However, other invoice parsers may choose a
different hash. If a service’s invoice parser and Lightning node use
different hashes, the service could misinterpret a completed withdrawal as
unpaid, which could result in two payments being made. Rejecting duplicates
removes that ambiguity. BOLT11 already requires invoice creators to include
exactly one p field; BOLTs #1357 proposes requiring readers to reject
duplicates.
● LND #11212 removes support for opening or accepting new channels using
the legacy commitment format, aligning with BOLT2 (see Newsletter
#305). Legacy commitments derive the key for the output
paying the counterparty (to_remote) using a per-commitment point. If a node
loses its channel state, recovering funds from its peer’s commitment
transaction therefore requires that peer to supply the missing point. Static
remote key channels keep this output key unchanged across channel updates,
avoiding that dependency (see Newsletter #67).
Existing legacy channels remain usable. Eclair made the same change last year (see Newsletter #378).
● LND #11258 fixes a bug where forwarded HTLCs could remain
unresolved if LND restarted after the outgoing channel was closed and its
records cleaned up. Previously, channel cleanup could delete a received
settlement or failure response before it was locked into the incoming
channel. This could leave the incoming HTLC stuck, resulting in an
unnecessary force close of the incoming channel and additional onchain fees.
Now, LND saves pending responses separately from the closed channel, retains
the information needed to match them to incoming HTLCs, and replays them on
startup.
