This week’s newsletter describes a proposed soft fork to enable a new
type of fee bumping and summarizes research into scripts that can never
be spent because they require satisfying both timelocks and heightlocks.
Also included are our regular sections with summaries of updates to
services and client software, a list of new releases and release
candidates, and changes to popular Bitcoin infrastructure software.
Action items
None this week.
News
-
● Transaction fee sponsorship: Jeremy Rubin posted a proposal to the Bitcoin-Dev mailing list for a soft fork to
add a new fee bumping mechanism that could be less vulnerable to abuse
than the current Replace-by-Fee (RBF) and
Child-Pays-For-Parent (CPFP) methods. Transacting
pinning and other abuses
against the existing system can be used to attack contract
protocols. These problems have led to partial solutions such as anchor
outputs that work with specific protocols (e.g.
two-party LN channels) but aren’t easy to generalize and so are
somewhat unsatisfactory.At the consensus layer, Rubin proposes allowing transactions to optionally contain a special final output that commits to the txids of one or more other unconfirmed transactions. The transaction with the special output, called a sponsor transaction, may only be included in a valid block if every one of the transactions it sponsored is also included in that same block. This means a miner who wants the high feerate from a sponsor transaction will be incentivized to confirm low-feerate sponsored transactions. Beyond their special sponsorship output, sponsor transactions are normal Bitcoin transactions.
For the rules that control mempool acceptance and transaction relay (the policy layer), Rubin suggests a set of simple changes that allow anyone to sponsor any transaction currently in a mempool or to replace an existing sponsor transaction with a higher feerate alternative that makes the same commitment. The goal is to ensure that, as long as a sponsor transaction follows the rules and pays a high enough feerate, it will propagate across the network without running afoul of pinning or other attacks.
Rubin’s proposal comes with a reference implementation and discussion of design tradeoffs and forward compatibility. As of this writing, comments on the list have shown appreciation for Rubin’s work but also describe two significant complications:
-
● Floating payments still pinnable: Antoine Riard notes that, even with a change to the proposal to allow sponsoring particular inputs,
a malicious counterparty can pin a particular input signed with
SIGHASH_SINGLE
(e.g. HTLCs in the latest LN protocol or state
transactions in eltoo) by including that input in a
maximum size transaction. -
● Breaks reorg safety guarantee: Suhas Daftuar reminds readers of a founding principle of Bitcoin’s design. As
Satoshi Nakamoto wrote, “In the event of a
block chain reorg […], transactions need to be able to get into
the chain in a later block.” This principle is broken by sponsor
transactions which are only valid in the same block as the
transactions they sponsor.
The proposal was still being actively discussed just hours before publication of this newsletter. We’ll summarize any new notable discussion in future editions.
-
-
● Research into conflicts between timelocks and heightlocks: A
post to the Blockstream engineering blog describes
an interaction between different types of Bitcoin time locks
(timelocks) and block-height locks (heightlocks). All transactions
since Bitcoin’s initial release have had annLockTime
field. A soft
fork activating at block 31,000 (December 2009) began
comparing this field against a block header’s
explicit time field and its implicit height (number of blocks since
the Genesis Block). A block is only valid if
every one of its transactions follows these two
rules:1-
If a transaction’s nLockTime is below 500 million, it must also be
below the block’s height. -
If a transaction’s nLockTime is equal to or above 500 million, it
must be below the block header’s time (in epoch time).
This overloading of the single nLockTime field for two different purposes is efficient but has the obvious implication that a transaction can only use either a heightlock or timelock—not both.
Years later, the BIP65 soft fork activated in December 2015 added the
OP_CHECKLOCKTIMEVERIFY
(CLTV) opcode that compares its argument against its spending transaction’s nLockTime field in the same way the nLockTime field is compared to the containing block’s height or time field. This allows scripts to prevent money received to them from being spent until after a certain future height or time. However, the Blockstream post explains that this also has the non-obvious implication that it’s possible to create a script that’s unspendable because it requires the simultaneous use of both heightlocks and timelocks. For example, a payment to the following script can never be spent:1 OP_CLTV OP_DROP 500000001 OP_CLTV
The first condition allows the spending transaction to be included in block 1 or later, so any block after early January 2009, and the second condition allows it to be included in any block after early November 1985. Both conditions are true today—but they can’t both be satisfied using a transaction’s single nLockTime field. The post notes that the same problem can apply when a transaction has multiple inputs each with their own script. For example:
Input 0: 1 OP_CLTV Input 1: 500000001 OP_CLTV
The problem also applies to relative timelocks and relative heightlocks created using BIP68 sequence numbers and the BIP112
OP_CHECKSEQUENCEVERIFY
opcode.The post notes that the Miniscript compiler has been updated to deal with the possible conflicts as best as possible. It will identify when one or more of the ways to satisfy a script contains conflicting locks and will return a warning. Because of the conflict, it’ll also not be able to provide a full analysis of the script. Additionally, the compiler for the policy language will now deliberately fail on policies that mix timelocks and heightlocks, e.g.
thresh(3,after(1),after(500000001),pk(A))
. Note: as of this writing, this change is only a pending PR to the Rust version of the miniscript library and has not yet propagated to the online live demos for miniscript or minsc. -
Changes to services and client software
In this monthly feature, we highlight interesting updates to Bitcoin
wallets and services.
-
● Swan supports sending to bech32 addresses:
Swan, through their custodian Prime Trust, now supports withdrawals
to bech32 addresses. -
● Ledger Live adds manual coin selection support:
Moving from a first-in, first-out UTXO selection model, Ledger Live now also
supports manual coin selection for either privacy
or fee-minimization benefits. -
● Sparrow wallet announced:
Sparrow wallet is a new desktop wallet supporting
single or multisignature addresses, PSBT, hardware wallets, and coin
selection. -
● JoinMarket 0.7.0 adds BIP78, PSBT:
JoinMarket 0.7.0 includes support for BIP78 payjoin
for payments. PSBT support was also added in order to facilitate the implementation.
Releases and release candidates
New releases and release candidates for popular Bitcoin infrastructure
projects. Please consider upgrading to new releases or helping to test
release candidates.
- ● LND 0.11.1-beta.rc4 is the release candidate for a
minor version. Its release notes summarize its changes as, “a number
of reliability improvements, some macaroon [authentication token]
upgrades, and a change to make our version of anchor commitments spec compliant.”
Notable code and documentation changes
Notable changes this week in Bitcoin Core,
C-Lightning, Eclair, LND,
Rust-Lightning, libsecp256k1,
Hardware Wallet Interface (HWI), Bitcoin Improvement Proposals
(BIPs), and Lightning BOLTs.
-
● Bitcoin Core #16378 adds a new
send
RPC to the wallet. This new
RPC is designed for maximum flexibility and includes options such as
multiple outputs (allowing payment batching), coin selection, manual or automatic feerates, and PSBT format. It is
intended to unify the functionality of thesendtoaddress
andsendmany
RPCs,
which may be deprecated in a future release. For the full list of
options, see the RPC help text. -
● Bitcoin Core #19643 adds a new
-netinfo
option to thebitcoin-cli
command to display a peer connection dashboard. This dashboard offers
node operators a bird’s-eye view of peer connection details such as
directionality, relay type, network family, and uptime. An optional
argument from0
to4
may be passed to display various levels of
detail.$ watch -n 0.1 ./src/bitcoin-cli -netinfo 3 Bitcoin Core v0.20.99.0-bf1f913c44 - 70016/Satoshi:0.20.99/ Peer connections sorted by direction and min ping <-> relay net mping ping send recv txn blk uptime asmap id version in full onion 1 1 0 10206 70015/Satoshi:0.20.1/ in full ipv6 246 246 1 9 0 1 16509 10202 70015/Satoshi:0.19.1/ in block onion 37686 425955 42 42 25 10143 70015/Satoshi:0.20.1/ [...] out full ipv4 94 198 3 1 0 229 956 12998 7809 70015/Satoshi:0.19.0.1/ out block ipv6 107 269 64 64 949 5577 7835 70015/Satoshi:0.16.0/ out full onion 440 1180 4 4 0 257 9574 70015/Satoshi:0.18.1/ ms ms sec sec min min min ipv4 ipv6 onion total block-relay in 0 17 8 25 2 out 8 2 8 18 2 total 8 19 16 43 4 Local addresses [redacted] port 8333 score 6401 [redacted].onion port 8333 score 1085
-
● Bitcoin Core #15454 no longer creates a new wallet when the
program is started for the first time. Instead, the user is prompted
to either load an existing wallet or create a new named wallet.
Wallets created by default in earlier versions of the software will
still be loaded by default, and newly created wallets can still be
added to the load-on-start list (see Newsletter #111). By removing the default wallet creation, users
gain more exposure to the options for customizing their wallet
options, such as enabling wallet encryption, creating a watch-only
wallet, or creating a wallet that’s ready to import output script
descriptors (e.g. for multisig). -
● Bitcoin Core #19940 updates the
testmempoolaccept
RPC with
additional result fields for the transaction’s vsize and total transaction fee if the
transaction can be added to the mempool. In particular, the fee is
information that some users need, which is guaranteed to be available
for a mempool transaction, and which cannot be trustlessly obtained
before broadcasting a non-wallet transaction unless several other RPCs
are run in sequence (e.g. usingdecoderawtransaction
and
getrawtransaction
). -
● LND #4440 records the number of times the local node sees a peer
going offline and then coming back online, known as flapping. The
node will limit the number of event records it’ll store about peers
who frequently flap to avoid filling its database with too much noise.
Thelistchannels
RPC is also updated to display each peer’s flap
rate. -
● LND #4567 adds a new
--maxchansize
configuration parameter that
allows setting the maximum amount of money that can be contained in a
new channel. Now that LND supports large channels (see Newsletter #107), this setting
allows users to set a limit on the maximum amount of money they could potentially
lose in a single channel if something goes wrong. -
● LND #4606 and #4592 improves LND’s effectiveness at
fee bumping anchor outputs. The first PR
calculates the feerate needed to confirm both the child anchor
transaction and its parent commitment transaction. The second PR
enables automatic fee bumping when a commitment transaction needs to
be confirmed within the next several blocks.
Footnotes
-
Timelocks and heightlocks based on a transaction’s nLockTime are a
bit more complicated than described here due to an interaction
with a transaction’s one or more nSequence fields. If all nSequence
fields are set to their maximum value (0xffffffff
), then the
transaction can be included in any block. For details about the
possible motivation for the interaction between nLockTime and
nSequence (and signature hash flags), see an email with quotes attributed to Satoshi Nakamoto.Additionally, the BIP113 soft fork activated in July 2016 means
nodes now compare timelock values to a block’s computed Median Time
Past (MTP) rather than its explicit header time. ↩