lnd/docs/release-notes/release-notes-0.21.0.md
ziggie a10cd1699f
docs: add release note for network separation safeguard
This is in particular important when running with a postgres
backend.

This only works if you run LND with the native sql flag but
people should run it with this flag from 21 on anyways.
2026-04-10 12:04:04 +02:00

22 KiB

Release Notes

Bug Fixes

  • Fixed OpenChannel with fund_max to use the protocol-level maximum channel size instead of the user-configured maxchansize. The maxchansize config option is intended only for limiting incoming channel requests from peers, not outgoing ones.
  • Chain notifier RPCs now return the gRPC Unavailable status while the sub-server is still starting. This allows clients to reliably detect the transient condition and retry without brittle string matching.

  • Fixed TLV decoders to reject malformed records with incorrect lengths. TLV decoders now strictly enforce fixed-length requirements for Fee (8 bytes), Musig2Nonce (66 bytes), ShortChannelID (8 bytes), Vertex (33 bytes), and DBytes33 (33 bytes) records, preventing malformed TLV data from being accepted.

  • Fixed MarkCoopBroadcasted to correctly use the local parameter. The method was ignoring the local parameter and always marking cooperative close transactions as locally initiated, even when they were initiated by the remote peer.

  • Fixed a panic in the gossiper when TrickleDelay is configured with a non-positive value. The configuration validation now checks TrickleDelay at startup and defaults it to 1 millisecond if set to zero or a negative value, preventing time.NewTicker from panicking.

New Features

  • Basic Support for onion messaging forwarding. This adds a new message type, OnionMessage, comprising a path key and an onion blob. It includes the necessary serialization and deserialization logic for peer-to-peer communication.

Functional Enhancements

  • Added reorg protection for channel closes. Previously, channel closes were considered final immediately on spend detection with no confirmation waiting. Now, all channel closes require between 3 and 6 confirmations, scaled linearly with channel capacity up to the maximum non-wumbo channel size (~0.168 BTC), with wumbo channels always requiring 6 confirmations.

  • Added taproot channel support for RBF cooperative close. The new RBF-based cooperative close protocol (enabled with --protocol.rbf-coop-close) now fully supports simple taproot channels. This includes MuSig2 partial signature handling with the JIT (just-in-time) nonce pattern, where closer nonces are bundled with signatures in ClosingComplete and closee nonces are rotated via NextCloseeNonce in ClosingSig for each RBF iteration. The implementation prevents nonce reuse across RBF rounds by storing the MusigPartialSig in the protocol state machine and invalidating nonces after each signing round completes.

RPC Additions

  • Added DeleteForwardingHistory RPC to the router sub-server, allowing operators to selectively purge old forwarding events from the database. Deletion requires the target cutoff timestamp to be at least 1 hour in the past, preventing accidental removal of recent data.

  • The WaitingCloseChannel response in PendingChannels now includes two new fields via #10509: blocks_til_close_confirmed, showing the remaining confirmations until a closed channel is considered fully resolved, and close_height, the block height at which the closing transaction was first confirmed. These build on the reorg-safe confirmation logic introduced in #10331, where the required number of confirmations scales with channel capacity.

  • Added support for coordinator-based MuSig2 signing patterns with two new RPCs: MuSig2RegisterCombinedNonce allows registering a pre-aggregated combined nonce for a session (useful when a coordinator aggregates all nonces externally), and MuSig2GetCombinedNonce retrieves the combined nonce after it becomes available. These methods provide an alternative to the standard MuSig2RegisterNonces workflow and are only supported in MuSig2 v1.0.0rc2.

  • The EstimateFee RPC now supports explicit input selection. Users can specify a list of inputs to use as transaction inputs via the new inputs field in EstimateFeeRequest.

lncli Additions

Improvements

Functional Updates

RPC Updates

  • routerrpc HTLC event subscribers now receive specific failure details for invoice-level validation failures, avoiding ambiguous UNKNOWN results. #10520

  • A new wallet_synced field has been added to the GetInfo RPC response. This field indicates whether the wallet is fully synced to the best chain, providing the wallet's internal sync state independently from the composite synced_to_chain field which also considers router and blockbeat dispatcher states.

  • SubscribeChannelEvents now emits channel update events to be able to subscribe to state changes.

  • The GetDebugInfo RPC request now accepts an include_log flag. By default, only the configuration map is returned. When include_log is set to true, the log file content is also included in the response.

lncli Updates

  • The getdebuginfo command now supports an --include_log flag. By default, only the daemon's configuration is returned. When set, the log file content is also included in the response.

  • The encryptdebugpackage command now supports an --include_log flag. When set, the log file content is included in the encrypted debug package.

Breaking Changes

  • Increased MinCLTVDelta from 18 to 24 to provide a larger safety margin above the DefaultFinalCltvRejectDelta (19 blocks). This affects users who create invoices with custom cltv_expiry_delta values between 18-23, which will now require a minimum of 24. The default value of 80 blocks for invoice creation remains unchanged, so most users will not be affected. Existing invoices created before the upgrade will continue to work normally.

  • The GetDebugInfo RPC no longer returns log file content by default. Clients that rely on the log field must now explicitly set include_log to true in the request. The lncli getdebuginfo and lncli encryptdebugpackage commands similarly require the --include_log flag to include logs in the output.

Performance Improvements

  • Let the channel graph cache be populated asynchronously on startup. While the cache is being populated, the graph is still available for queries, but all read queries will be served from the database until the cache is fully populated. This new behaviour can be opted out of via the new --db.sync-graph-cache-load option.

  • Invoice pagination queries no longer use OFFSET. The five invoice filter queries previously used LIMIT+OFFSET for internal batching, which requires the database to scan and discard all preceding rows on every page. All pagination is now cursor-based (WHERE id >= cursor), making every page an efficient primary-key range scan regardless of how deep into the result set the query is.

  • Replace the catch-all FilterInvoices SQL query with five focused, index-friendly queries (FetchPendingInvoices, FilterInvoicesBySettleIndex, FilterInvoicesByAddIndex, FilterInvoicesForward, FilterInvoicesReverse). The old query used col >= $param OR $param IS NULL predicates and a CASE-based ORDER BY that prevented SQLite's query planner from using indexes, causing full table scans. Each new query carries only the parameters it actually needs and uses a direct ORDER BY, allowing the planner to perform efficient index range scans on the invoice table.

  • Fix full table scans on the HTLC settlement hot path. Replace the catch-all GetInvoice query (which used OR $1 IS NULL predicates that forced full table scans) with three dedicated queries targeting uniquely-constrained columns. Also drop four redundant indexes that duplicated UNIQUE constraints or were never used as query filters.

  • Optimize the v1 node horizon query. Split the GetNodesByLastUpdateRange query into separate all-nodes and public-only variants, removing a dynamic COALESCE/OR branch that defeated the query planner. The public-only EXISTS check is rewritten as two direct index probes instead of node_id_1 OR node_id_2. Supporting indexes are upgraded to composite keys matching the full query shapes. On SQLite, the hot public-only path sees a ~42% speedup; on the previous code it could stall for minutes.

Deprecations

⚠️ Warning: Deprecated fields in lnrpc.Hop will be removed in release version 0.22

The following deprecated fields in the lnrpc.Hop message will be removed:

Field Deprecated Since Replacement
chan_capacity 0.7.1 None
amt_to_forward 0.7.1 amt_to_forward_msat
fee 0.7.1 fee_msat

⚠️ Warning: The deprecated fee rate option --sat_per_byte will be removed in release version 0.22

The deprecated --sat_per_byte option will be fully removed. This flag was originally deprecated and hidden from the lncli commands in v0.13.0 (PR#4704). Users should migrate to the --sat_per_vbyte option, which correctly represents fee rates in terms of virtual bytes (vbytes).

Internally --sat_per_byte was treated as sat/vbyte, this meant the option name was misleading and could result in unintended fee calculations. To avoid further confusion and to align with ecosystem terminology, the option will be removed.

The following RPCs will be impacted:

RPC Method Messages Removed Option
lnrpc.CloseChannel lnrpc.CloseChannelRequest sat_per_byte
lnrpc.OpenChannelSync lnrpc.OpenChannelRequest sat_per_byte
lnrpc.OpenChannel lnrpc.OpenChannelRequest sat_per_byte
lnrpc.SendCoins lnrpc.SendCoinsRequest sat_per_byte
lnrpc.SendMany lnrpc.SendManyRequest sat_per_byte
walletrpc.BumpFee walletrpc.BumpFeeRequest sat_per_byte

Technical and Architectural Updates

BOLT Spec Updates

Testing

Database

Code Health

  • Update taproot detection to accommodate buried activation (and modified RPC getdeploymentinfo response) beginning in Bitcoin Core v32.

Tooling and Documentation

  • Added missing lncli: tags for SendPaymentV2, SendToRouteV2, and EstimateRouteFee in the routerrpc proto definitions so that the generated API documentation correctly links to their corresponding lncli commands (sendpayment, sendtoroute, estimateroutefee).

  • Overhauled Docker documentation and environment to modernize the developer onboarding flow. Key updates include migrating to Docker Compose V2, updating base images (btcd v0.25.0, Go 1.25.5), and transitioning the documentation to focus on a more reliable "Simnet" workflow while removing obsolete faucet references.

  • Android Lndmobile 16 KB page size for native libraries The Android Lndmobile.aar build now passes -Wl,-z,max-page-size=16384 to the linker, keeping the generated native library compatible with newer Android devices that use 16 KB memory pages while preserving compatibility with existing 4 KB page-size devices.

Contributors (Alphabetical Order)

  • bitromortac
  • Boris Nagaev
  • Elle Mouton
  • Erick Cestari
  • Gijs van Dam
  • hieblmi
  • Matthew Zipkin
  • Mohamed Awnallah
  • Nishant Bansal
  • Pins
  • Suheb
  • Ziggie