Commit graph

20799 commits

Author SHA1 Message Date
George Tsagkarelis
22be7db188 docs: add release note 2026-05-13 13:53:00 +00:00
George Tsagkarelis
3a5e816d5e routing: add test with ineffective second chance
We add a test to demonstrate that the second chance penalty can be
effective. In this test an initially cheap route is attempted but errors
with a new returned channel policy. After applying that policy we should
pick the cheaper route again, but the second-chance penalty will prevent
us from doing so. Instead an alternative route succeeds.
2026-05-13 13:53:00 +00:00
George Tsagkarelis
98246b36fa routing: adjust impact of pathfinding second chance
Previously our mission control would not punish a route if a policy
failure was provided to us, in the form of a "second chance". For
various reasons outlined in
https://github.com/lightningnetwork/lnd/issues/6883 we may not want to
blindly retry a route if that case is true.

With this commit we change the effect of the second chance to instead
apply penalties with half the value. This way we do not exclude this
route from future attempts and also encourage alternative route
selection.
2026-05-13 13:45:13 +00:00
Elle
1c5df12ffa
Merge pull request #10796 from ellemouton/for-each-node-cached-autopilot
autopilot+graph/db: drop unused address loading from cached node iteration
2026-05-12 16:00:53 -07:00
Elle Mouton
c18f139e24
docs: add release note for autopilot graph-cache fix
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.
2026-05-12 12:39:51 -07:00
Elle Mouton
d0e9042944
autopilot: pass pubkey in channel traversal
ForEachNodesChannels is a topology traversal: its callers only need
the node identity plus channel edges. After removing address loading
from ForEachNodeCached, constructing a Node for this callback is
misleading because Addrs is either unused or empty.

Pass NodeID directly through the interface and update the scoring
and simple graph callers to use that pubkey. This keeps the
address-bearing Node interface on ForEachNode, where autopilot
gathers connectable candidates and their addresses before dialing.
2026-05-12 12:39:51 -07:00
Yong
3ba3eaaff4
Merge pull request #10612 from Abdulkbk/onion-msg-path
onionmessage: graph-based pathfinding for onion messages
2026-05-13 00:42:38 +08:00
Yong
3adf45d3ab
Merge pull request #10777 from ziggie1984/chanstate-sql-migration-pr1-interface
chanstate: introduce Store interface (PR 1 of channel-state decomposition)
2026-05-12 11:27:34 +08:00
Yong
530ebccfbb
Merge pull request #10765 from erickcestari/enforce-bolt02-push-msat-bound
funding: enforce BOLT-02 push_msat bound on fundee
2026-05-12 09:41:02 +08:00
ziggie
96e0fd7447
chanstate: introduce Store interface
Add a new chanstate package containing the Store interface plus a
package logger. The interface mirrors the public surface of
*channeldb.ChannelStateDB so the compile-time assertion

    var _ ChannelStore = (*channeldb.ChannelStateDB)(nil)

No consumer migrates in this commit.
2026-05-11 18:54:30 -03:00
ziggie
bb8eeb2304
channeldb: drop unused kvdb.RTx parameter from FetchChannelByID
All four call sites pass nil for tx today (server.go, two in
channeldb/db_test.go, funding/manager_test.go). The internal
channelScanner(nil, selector) call inside FetchChannelByID is preserved
verbatim, so runtime behavior is unchanged.

This is a prerequisite for the upcoming chanstate.ChannelStore
interface: keeping the parameter would leak kvdb into a domain
interface.
2026-05-11 18:03:10 -03:00
Erick Cestari
bb8abc7516
docs: release note for BOLT-02 push_msat fundee enforcement
Document the user-visible error string change introduced when the
fundee rejects incoming open_channel messages whose push_msat exceeds
1000 * funding_satoshis.
2026-05-11 14:22:10 -03:00
Erick Cestari
d5505498c4
funding: enforce BOLT-02 push_msat bound on fundee
Reject incoming OpenChannel messages where push_msat exceeds
1000 * funding_satoshis, as required by BOLT-02. The existing RejectPush
flag only gates on push_msat > 0 and does not cover the spec bound.

An over-sized push is eventually caught downstream in reservation.go when
theirBalance = capacity - fee - push_msat goes negative and
ErrFunderBalanceDust is returned. Rejecting it up front produces a
clearer, spec-aligned error and avoids the chanacceptor and commitment
type negotiation round-trips for a channel we will refuse anyway.
2026-05-11 14:20:39 -03:00
Elle Mouton
bfb12b1d81 graph/db: remove address loading from cached node iteration
ForEachNodeCached is now only used for topology-oriented traversal,
so the address-loading option forced one autopilot scoring path to
bypass the in-memory graph cache for data it did not consume. Remove
the withAddrs parameter and the associated SQL/KV address plumbing
so cached node iteration can consistently use the graph cache when
it is loaded.

Autopilot still requires peer addresses before opening channels.
That filtering remains in Agent.openChans via ForEachNode, where the
selected candidates' addresses are collected for ConnectToPeer. The
trade-off is that ForEachNodesChannels no longer excludes
addressless nodes from graph-wide scoring inputs such as median
channel size or centrality, which also feed lncli getnetworkinfo
statistics like graph diameter. In practice the only addressless
nodes our local view tends to know about are nodes with no public
channels (e.g. our own node or peers we share only private channels
with), so the impact on the reported stats should be negligible.
Active channel candidates remain address-filtered before dialing.
2026-05-07 16:29:12 -07:00
Olaoluwa Osuntokun
50eb0d1466
Merge pull request #10793 from aakselrod/fix-sqlbase-nonconst-fmt-strings
kvdb/sqlbase: fix non-constant format strings
2026-05-07 13:31:52 -05:00
Alex Akselrod
ce65753d0f
kvdb/sqlbase: fix non-constant format strings
When updating the Go version in kvdb to >= 1.24, schema.go no
longer compiles due to non-constant format strings. This is
invisible until:
- a new version of kvdb is tagged and imported in consumers
- kvdb is redirected to the local copy

This commit fixes the bug.
2026-05-06 13:09:59 -07:00
ziggieXXX
6fd5b7bb27
Merge pull request #10780 from ziggie1984/channeldb-tombstone-close
channeldb: tombstone closed channels on KV-SQL backends
2026-05-04 12:11:00 -03:00
ziggie
1a52e85b94
docs: release note for closed-channel tombstones on KV-SQL backends
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.
2026-05-04 09:46:33 -03:00
ziggie
9504412478
multi: enable closed-channel tombstones on KV-SQL backends
Wire OptionTombstoneClosedChannels for sqlite and postgres backends in
config_builder.go. bbolt keeps the synchronous one-shot close path
unchanged.

Add UsesClosedChanTombstones() to the integration test harness so
backend-symmetric tests can skip post-close assertions about deleted
forwarding-package or revocation-log state — that state is intentionally
preserved on tombstone backends until the upcoming native-SQL
channel-state migration reclaims it. Update testWipeForwardingPackages
to honor the new predicate while still exercising the close flow on
both backend families.
2026-05-04 09:46:32 -03:00
ziggie
dc4b851454
channeldb: hide tombstoned channels from open views
Wire every reader of openChannelBucket to consult isOutpointClosed
before treating a chanKey as open. Without this commit the previous one
flips the outpoint index but FetchAllChannels and friends still surface
the channel as if it were open — that intermediate state is fine for
tests because OptionTombstoneClosedChannels stays off until the multi:
commit flips it on for sqlite/postgres, but the readers must be wired
before that lands.

Audit covers all six call sites that descend into chanBucket:

  - fetchChanBucket / fetchChanBucketRw — direct lookup paths used by
    Refresh, MarkBorked, and the rest of OpenChannel's read/write
    methods. Single-call sites; the tx.ReadBucket(outpointBucket)
    lookup is inlined into the isOutpointClosed call.
  - fetchNodeChannels — per-node ForEach iteration; tx threaded
    through and the outpoint-bucket lookup is hoisted above the loop
    so the closed-channel check is a per-iteration map probe rather
    than a tx-level bucket resolve.
  - FetchPermAndTempPeers — cross-node ForEach; same hoisting pattern.
    The closed peer's protected status is still established by the
    historical-channel second pass that runs after the open-channel
    pass.
  - channelScanner — single-channel-selector iteration site reached by
    FetchChannel and FetchChannelByID; outpoint-bucket lookup hoisted
    inside chanScan so a single visit pays the bucket-resolve cost
    once.

The redundant-close guard added in the previous commit lives in
locateOpenChannel and is unchanged here.

Tests:
  - TestCloseChannelTombstoneRemovesFromOpenScans: end-to-end —
    FetchAllChannels, FetchOpenChannels, and FetchPermAndTempPeers all
    behave as if the closed channel is gone, while the historical pass
    still marks the peer as having a closed channel.
  - TestClosedChannelHiddenFromFetchChannel: channelScanner path.
  - TestClosedChannelHiddenFromDirectMethods: fetchChanBucket /
    fetchChanBucketRw via Refresh and MarkBorked.
2026-05-04 09:46:32 -03:00
ziggie
d643050dfb
channeldb: tombstone closed channels without bulk delete
Wire the tombstone close path on backends that opted in via
OptionTombstoneClosedChannels:

  - ChannelStateDB.CloseChannel branches on tombstoneClosedChannels.
    The default path remains closeChannelSync; closeChannelTombstone
    runs on tombstone-enabled backends.
  - closeChannelTombstone leaves every byte of the channel's nested
    state in place — chanBucket, revocation log, per-channel
    forwarding-package bucket, commitment heads — and relies on the
    outpointBucket flip from outpointOpen to outpointClosed (already
    performed by the shared updateClosedOutpointIndex helper) as the
    authoritative closed-channel marker. The historical-channel and
    close-summary archival use the same archiveClosedChannel helper as
    the synchronous path so closed-channel and historical readers see
    uniform records regardless of backend.
  - locateOpenChannel rejects already-closed chanKeys (outpointClosed
    in the index) with ErrChannelNotFound so a redundant CloseChannel
    is a no-op rather than a re-archive.

Open-channel-bucket readers still surface tombstoned channels — that
audit lands in the next commit. The tests added here only assert the
writer's on-disk artefacts and the redundant-close guard.

Tests:
  - TestCloseChannelTombstoneWritePath: outpoint flipped, historical
    record, close summary, revlog/fwd-pkgs preserved.
  - TestCloseChannelTombstoneRedundantClose: second CloseChannel
    returns ErrChannelNotFound.
  - TestCloseChannelSync: regression test for the synchronous path —
    chanBucket and fwd-pkgs gone, outpoint flipped.
2026-05-04 09:46:32 -03:00
ziggie
f94fba1e85
channeldb: add tombstone option and isOutpointClosed helper
Add the option, field, and reader helper that the tombstone close path
will consume in the next commit. Nothing is wired yet:

  - OptionTombstoneClosedChannels — option modifier that sets the new
    Options.tombstoneClosedChannels field. Defaults to off.
  - ChannelStateDB.tombstoneClosedChannels — the decision-bit, set at
    construction from the option.
  - isOutpointClosed(opBucket, chanKey) — decodes the indexStatus TLV
    stored under outpointBucket and reports true for entries flipped to
    outpointClosed by updateClosedOutpointIndex (called from both close
    paths). The helper accepts the bucket directly so loop-style
    callers can hoist the tx.ReadBucket(outpointBucket) lookup out of
    the inner loop and pay it once per iteration set.

Reusing outpointBucket as the "logically closed" signal avoids a
dedicated tombstone bucket. The flip from outpointOpen to outpointClosed
is already performed by the existing close path, so the signal exists on
both backends — readers just need to consult it.

Behavior is unchanged. The option and helper have no callers yet; the
close-path branch and reader audit land in the next two commits.
2026-05-04 08:58:32 -03:00
Yong
8df972d965
Merge pull request #9821 from lightningnetwork/coop-close-actor
multi: add new rbf coop close actor for RPC server fee bumps
2026-05-01 03:53:31 +08:00
ziggie
4815ed2b23
channeldb: extract close-channel helpers
Move the body of OpenChannel.CloseChannel into ChannelStateDB.CloseChannel
(which dispatches to a new closeChannelSync method), and split the close
logic into three free helpers:

  - locateOpenChannel: descends the open-channel bucket tree and returns the
    chain bucket, channel bucket, and serialized chanKey for an OpenChannel.
  - updateClosedOutpointIndex: flips the outpoint index entry for a chanKey
    from open to closed.
  - archiveClosedChannel: writes the historical-channel record and the close
    summary that survive the close.

Behavior is preserved: closeChannelSync runs the same sequence of mutations
(packager wipe, chanBucket delete, log-bucket delete, outpoint flip,
historical archive, close summary) that the inline body did, just composed
out of the new helpers. No callers, options, or readers change.

This is preparation for adding a tombstone close strategy on KV-SQL
backends; the helpers will be shared between the synchronous and tombstone
paths so historical and closed-channel records remain identical across
backends.
2026-04-30 09:08:00 -03:00
Abdullahi Yunus
72873f6275
docs: add release not for pathfinding 2026-04-29 22:34:44 +01:00
Abdullahi Yunus
fd25ba9853
onionmessage: add BFS pathfinding for onion messages
In this commit we add FindPath, a BFS-based shsortest-path
algorithm that finds routes through the channel graph for
onion messages. The search filters nodes by the
OnionMessage feature bits (38/39).

We also add a  unit tests covering: direct neighbor routing,
multi-hop paths, feature-bit filtering, missing destination
nodes, destination without onion support, max hop limits,
cycle handling, and shortest-path selection.
choice of BFS is because there isn't any weight involve.
2026-04-29 22:34:44 +01:00
ziggieXXX
746ed3c137
Merge pull request #10776 from ziggie1984/fix-release-notes-0.21.0-contributors-anchor
docs: fix Contributors TOC anchor in v0.21.0 release notes
2026-04-28 19:22:40 -03:00
ziggie
c0b417c79c
docs: fix Contributors TOC anchor in v0.21.0 release notes
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).
2026-04-28 16:40:23 -03:00
ziggieXXX
caccaf3cf1
Merge pull request #10775 from ziggie1984/release-notes-0.22.0
docs: add empty release notes scaffold for v0.22.0
2026-04-28 15:24:48 -03:00
ziggie
fa588eaf1a
docs: add empty release notes for v0.22.0
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.
2026-04-28 11:45:07 -03:00
ziggieXXX
1ddcd081ed
Merge pull request #10768 from yyforyongyu/9985-breach-arb
contractcourt: make breach retribution final-taproot aware
2026-04-27 21:35:02 -03:00
Yong
5b85551a97
Merge pull request #10725 from ziggie1984/lnwallet/fix-neutrino-reorg-wallet-sync-timeout
lnwallet/test: fix flaky neutrino reorg sync timeout
2026-04-27 13:21:33 +08:00
Yong
af1fc43fb7
Merge pull request #10689 from ziggie1984/bump-bitcoind-v30
scripts+GitHub: use bitcoind v30.0
2026-04-27 09:33:06 +08:00
ziggie
3cf60bd474
lnwallet/test: fix flaky neutrino reorg sync timeout
waitForWalletSync used time.Tick inside the poll loop, leaking a new
goroutine on every iteration. Over 5 reorg cycles with ~300 polls each
this accumulated up to 1500 leaked goroutines, adding measurable system
load that made the 30s timeout too tight, especially when running against
a postgres backend where block-processing writes carry more overhead.

Fix the leak by using a single time.NewTicker (deferred Stop), and raise
the timeout to 2 minutes to give the neutrino P2P layer and the
address-manager transaction walk enough headroom under load.

Also improve the timeout error messages to identify which of the two
sync layers was stuck:
- Layer 1 (header/P2P): ChainIO.GetBestBlock height has not yet caught
  up to the miner tip — neutrino is still fetching headers.
- Layer 2 (transaction walk): heights matched but IsSynced() never
  returned true — the chain-sync notification or the address-manager
  DB write (undo+redo on reorg) did not complete in time.

Add a detailed doc comment to waitForWalletSync explaining the three
pipeline stages (header sync, compact-filter/block fetch, transaction
walk) and why each stage is relevant, so a future timeout can be
diagnosed from the error message alone.
2026-04-26 22:32:33 -03:00
Yong
acb8f1c92e
Merge pull request #10715 from yyforyongyu/fix/ci-sweep-watchtower-flakes
itest+lntest: harden sweep and watchtower flakes
2026-04-27 09:19:57 +08:00
yyforyongyu
4d374fb5df
contractcourt: make breach retribution final-taproot aware 2026-04-24 18:48:31 +08:00
ziggie
651e5e6e7b
GitHub: bump itest bitcoind to v31
Bitcoin Core v31.0 was released on 2026-04-20. Update the CI itest
matrix to track the latest major release.
2026-04-23 11:33:50 -03:00
ziggie
6914ea0b1a
lntest: pin pre-v30 mempool policy defaults in itest bitcoind
Bitcoind v30 lowered the default minrelaytxfee and incrementalrelayfee
from 1000 sat/kvB (1 sat/vB) to 100 sat/kvB. The itest suite was
written against the old defaults and the lower values cascade into:

  - integer sat/vByte assertions losing precision below 1 sat/vB, and
  - RBF bump thresholds that alter sweeper/bumpfee replacement timing.

Pin the old defaults in the itest bitcoind backend so the existing
tests keep passing without per-test adaptation. Running against the
new defaults is still worth doing, but that is a separate exercise
that should not be bundled with the v30 version bump.
2026-04-23 11:27:41 -03:00
ziggie
154e507675
testing: allow patch versions of bitcoin core 2026-04-23 11:27:41 -03:00
Olaoluwa Osuntokun
07f54ae173 lnwallet/chancloser: create unique ServiceKey for the RBF chan closer
This can be used to allow any system to send a message to the RBF chan
closer if it knows the proper service key. In the future, we can use
this to redo the msgmux.Router in terms of the new actor abstractions.
2026-04-22 17:33:04 -07:00
Olaoluwa Osuntokun
ac4bc2392d protofsm: implement the actor.ActorBehavior interface for StateMachine
In this commit, we implement the actor.ActorBehavior interface for
StateMachine. This enables the state machine executor to be registered
as an actor, and have messages be sent to it via a unique ServiceKey
that a concrete instance will set.
2026-04-22 17:33:04 -07:00
Olaoluwa Osuntokun
fa2d0f9904 peer: register the rbfCloseActor, have RPC route fee bumps to it
In this commit, we now register the rbfCloseActor when we create the rbf
chan closer state machine. Now the RPC server no longer neesd to
traverse a series of maps and pointers (rpcServer -> server -> peer ->
activeCloseMap -> rbf chan closer) to trigger a new fee bump.

Instead, it just creates the service key that it knows that the closer
can be reached at, and sends a message to it using the returned
actorRef/router. We also hide additional details re the various methods
in play, as we only care about the type of message we expect to send and
receive.
2026-04-22 17:33:04 -07:00
Olaoluwa Osuntokun
2a3ae1efe8 peer: create new rbfCloseActor to decouple RPC RBF close bumps
In this commit, we create a new rbfCloseActor wrapper struct. This will
wrap the RPC operations to trigger a new RBF close bump within a new
actor. In the next commit, we'll now register this actor, and clean up
the call graph from the rpc server to this actor.
2026-04-22 16:46:55 -07:00
ziggie
752ad163fa
scripts+GitHub: use bitcoind v30.0 2026-04-21 21:56:04 -03:00
Yong
a8a3e13120
Merge pull request #10763 from GeorgeTsagk/taproot-final-acceptor
multi: fix SIMPLE_TAPROOT_FINAL acceptor and overlay RBF auto-enable
2026-04-21 16:47:39 +08:00
George Tsagkarelis
33f623c855
docs: add release note for SIMPLE_TAPROOT_FINAL follow-ups
See https://github.com/lightningnetwork/lnd/pull/10763.
2026-04-20 16:11:31 +02:00
George Tsagkarelis
6d95154801
server: do not auto-enable RBF coop close for overlay channels
An earlier commit added an auto-enable that forces RbfCoopClose=true
whenever either taproot channel flag is set. This breaks
taproot-overlay channels, because the RBF coop close state machine in
lnwallet/chancloser/rbf_coop_*.go does not integrate the AuxCloser
(or any other aux) hook that overlay channels depend on to build
aux-aware close transactions. A node that enables
--protocol.simple-taproot-overlay-chans ends up with RBF force-on and
its overlay channel closes silently fail, leaving the aux closer
unable to finalize on-chain.

Narrow the auto-enable so it only fires for TaprootChans (staging /
final taproot) and explicitly skips it when TaprootOverlayChans is set.
Operators that positively want RBF can still opt in via
--protocol.rbf-coop-close; this change only removes the forced path
that silently breaks overlay closes.
2026-04-20 16:00:26 +02:00
George Tsagkarelis
58231f1ff8
chanacceptor: map SIMPLE_TAPROOT_FINAL in rpc acceptor
The feature-bits-to-lnrpc-enum switch in sendAcceptRequests covered
every commitment type the RPC acceptor can be asked about, except the
production taproot variant introduced alongside the prod-taproot-chans
work. For a channel open using SimpleTaprootChannelsRequiredFinal (with
any combination of the scid-alias / zero-conf modifiers), the switch
fell through to the default branch, which logs a warning and leaves
commitmentType at its zero value -- lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE.
External acceptor clients then see UNKNOWN rather than the actual
commitment type and either reject or misclassify the channel.

Add the four missing cases so the new commitment type is reported to
acceptor clients correctly.
2026-04-20 16:00:25 +02:00
Yong
8f73764547
Merge pull request #10762 from yyforyongyu/update-release-notes
docs: add missing 0.21.0 contributors
2026-04-20 16:07:27 +08:00
yyforyongyu
e12435ef0c
docs: update contributor list 2026-04-20 13:33:38 +08:00