Use strict metadata reads during migration selection so a metadata bucket with a
missing metadata/dbp key is not interpreted as the latest DB version.
Recover this state from mandatory DB version 33, the last mandatory version
before the v0.20.x releases that could initialize a DB without writing the DB
version key. This runs migration 35 without replaying migrations 0 through 33
against a DB that was already created by a modern schema/code path.
After the selected migrations complete, syncVersions writes the latest DB
version as usual.
On an already-seen channel, the loop returned from the whole node
callback instead of continuing, skipping the node's remaining
channels, this undercounted the stats.
Add a 0.21 release-notes entry covering the `--tor.v2` removal, the
boundary rejection of v2 input on operator entry points, the
persisted-state filtering (self-node announcement, watchtower client,
autopilot, graph bootstrapper, SCB restore), the Tor controller's
v3-only ADD_ONION restriction, and the wire-faithful behavior that
preserves peer-signed v2 entries through `lnwire`, `graph/db`, and
the graph RPCs.
In this commit, we add three focused unit tests in contractcourt
plus an itest that exercises the regression end-to-end.
The chain watcher harness gains an opt-in early-dispatch capture that
records every notifyEarlyCoopClose invocation so tests can assert how
many fired and what summaries they carried. On top of that:
TestEarlyDispatchCoopClose verifies the headline behavior. An
async-path coop close fires exactly one early dispatch with
IsPending=true and the post-N-conf flow still produces the regular
CooperativeCloseInfo downstream.
TestEarlyDispatchForceCloseNotInvoked guards the carve-out: force
closes never fire the early dispatch since their CLOSED_CHANNEL
event timing is intentionally unchanged.
TestEarlyDispatchReorgRefiresOnReReplacement nails down the reorg
path. Once a deep reorg removes the close, the early-dispatch flag
is cleared and the next coop close re-fires the early event with its
own summary, so a subscriber observes each distinct close attempt.
testZeroConfCoopCloseSubscribeEvents brings up a zero-conf channel
between Alice and Bob with --dev.force-channel-close-confs=3 so the
chain watcher takes the async multi-confirmation path. Alice
subscribes to channel events, initiates a cooperative close, and the
test asserts that CLOSED_CHANNEL fires after only one confirmation
of the close tx (not after the full three) and that
FULLY_RESOLVED_CHANNEL arrives once the close has reached three
confirmations. A quiet-window assertion at the end verifies that
exactly one CLOSED_CHANNEL event is delivered. If the suppression in
MarkChannelClosed broke and let it re-fire NotifyClosedChannel at N
confs, this assertion would catch the duplicate.
In this commit, we shuffle the CLI and RPC names so the bare "taproot"
identifier refers to the production taproot channel type (final
scripts, feature bits 80/81), i.e. the variant new integrations should
actually be using. Before this commit, "taproot" on the CLI mapped to
the staging bits, and anyone who wanted a real production taproot
channel had to spell out "taproot-final" on `lncli openchannel` or
`SIMPLE_TAPROOT_FINAL` over RPC. The recommended choice was hidden
behind the longer name.
On the CLI (`lncli openchannel --channel_type=...`):
- "taproot" now selects the production variant (it used to mean
staging).
- "taproot-staging" is added for the legacy development bits, for
peers that haven't moved over yet.
- "taproot-final" stays as a deprecated alias for "taproot" so
existing scripts don't break.
On the RPC (`CommitmentType`):
- `TAPROOT = 7` is added as the canonical name for the production
type. `SIMPLE_TAPROOT_FINAL = 7` is kept as a deprecated alias via
`option allow_alias = true`, so existing clients keep compiling
against the same Go constant and the wire value doesn't change.
- `SIMPLE_TAPROOT = 5` (staging) is unchanged.
- `SIMPLE_TAPROOT_OVERLAY = 6` is unchanged. The taproot-assets
daemon hard-codes this distinct enum value, so it's unaffected.
Wire compat is preserved end-to-end: only the comments, enum entry
order, and the CLI string-to-enum mapping change. The numeric values
and the existing generated Go identifiers stay stable.
Document the neutrino fast sync feature that allows importing block and
filter headers from local files or HTTP URLs on startup. Cover
configuration for mainnet (block-dn.org), testnet3, testnet4, signet,
file format details, security considerations, and troubleshooting.
Add entries to the Breaking Changes section covering the payment and
tracking RPCs and the `outgoing_chan_id` field removed in this branch,
all of which were announced for removal in 0.21 via the 0.20 release
notes.
Document that bitcoind outbound peer health checks now use
getnetworkinfo.connections_out instead of getpeerinfo.
Also mention that texts of zmq port mismatch warnings were fixed.
Note the performance improvement from dropping the unnecessary address
load on the SQL backend and letting the kvdb in-memory graph cache
serve autopilot's scoring traversal.
Document the tombstone close path that #10780 wires onto sqlite/postgres,
the operator-visible iteration-cost growth that comes from leaving closed
chanBuckets on disk, and the NumForwardingPackages divergence that the
preserved forwarding-package bucket produces in PendingChannels.
The TOC link for the Contributors section pointed to `#contributors`,
but GitHub generates the anchor for `# Contributors (Alphabetical
Order)` as `#contributors-alphabetical-order`, leaving the link
broken when the rendered file is viewed on GitHub. Update the TOC
to use the working anchor (matching the form already used in
release-notes-0.18.0.md).
Scaffold release-notes-0.22.0.md with the same section structure as
the 0.21.0 file so contributors have a place to land entries during
the v0.22 cycle.