Commit graph

2475 commits

Author SHA1 Message Date
Gustavo Stingelin
0176e96e3c staticaddr: generate FSM diagrams 2026-07-20 12:07:26 -03:00
Gustavo Stingelin
e77a1ab634 fsm: harden diagram generation 2026-07-20 12:07:26 -03:00
Gustavo Stingelin
1d5b1c564a fsm: make diagram generation deterministic 2026-07-18 16:27:11 -03:00
Slyghtning
39c97e60d2
Merge pull request #1141 from lightninglabs/dyn-conf-tracker-staging
Some checks failed
CI / RPC compilation check (push) Has been cancelled
CI / SQL compilation check (push) Has been cancelled
CI / go mod check (push) Has been cancelled
CI / build and lint code (push) Has been cancelled
CI / verify that auto-generated documentation is up-to-date (push) Has been cancelled
CI / run unit-test sqlite3 race (push) Has been cancelled
CI / run unit-test postgres race (push) Has been cancelled
CI / run LiT itests (push) Has been cancelled
CI / run LiT unit tests (push) Has been cancelled
staticaddr: dyn-conf-tracker
2026-07-16 15:25:58 +02:00
Slyghtning
43b16ff3e1
cmd/loop: warn for low-confirmation static deposits
Warn before dispatching a static loop-in that selects deposits below
the conservative six-confirmation threshold. Mirror automatic coin
selection before prompting so the warning reflects both manual and
auto-selected deposits.

Cover manual and auto-selected warning paths in CLI tests.
2026-07-15 16:52:39 +02:00
Slyghtning
c718e9a9fb
staticaddr/loopin: retry failed deposit state transitions
Keep the loop-in monitor in its recoverable state when a required deposit transition or unlock fails. Only advance after every selected deposit reaches the expected state, and retry only deposits that remain pending after a partial transition.

Preserve shutdown semantics when observer cancellation races with a completed deposit update, and add regression coverage for transition, partial-transition, and unlock failures.
2026-07-15 16:52:39 +02:00
Slyghtning
6927c67b96
staticaddr/loopin: use risk decision watcher 2026-07-12 09:14:34 +02:00
Slyghtning
332aab79ed
staticaddr/loopin: add risk decision watcher 2026-07-12 09:14:34 +02:00
Slyghtning
6593afc8bc
staticaddr/loopin: recover risk-decision deadlines
Record replayed server risk decisions through the loop-in store,
recover accepted payment-deadline timers using the persisted decision
time, and handle persisted rejections on restart. This lets recovered
static loop-ins keep pending confirmation-risk state instead of
restarting payment timing from scratch.
2026-07-12 09:14:34 +02:00
Slyghtning
f01a1f02d9
staticaddr/loopin: clean up deposits after unpaid htlc timeout
Track whether the invoice was canceled for non-payment while monitoring
the HTLC. If the HTLC never confirms before timeout, unlock the
deposits; if it did confirm, transition them to the HTLC-timeout sweep
state without issuing duplicate transitions.
2026-07-12 09:14:34 +02:00
Slyghtning
3e2b9452fe
loopd: wire static risk decision persistence
Create the static loop-in SQL store before the notification manager and
pass a persistence callback so server confirmation-risk decisions are
durably recorded before fanout.
2026-07-12 09:14:34 +02:00
Slyghtning
e53bb67e73
notifications: persist static loop-in risk decisions
Persist static loop-in confirmation-risk decisions before fanout when a
persistence callback is configured. Keep unpersisted decisions cached
for replay so notification delivery is not lost if the swap row is not
available yet.
2026-07-12 09:14:33 +02:00
Slyghtning
491fddbc34
loopdb: persist static loop-in risk decisions
Add schema, sqlc queries, store fields, and SqlStore support for
recording server confirmation-risk decisions with static loop-in swaps.
Store the decision timestamp so payment-deadline recovery can
reconstruct elapsed time after restart.
2026-07-12 09:14:33 +02:00
Slyghtning
b0f43bbe1e
staticaddr/loopin: wait for risk decisions
Subscribe to static loop-in confirmation-risk notifications before
starting the payment deadline. Start that deadline only after server
acceptance or the legacy confirmation fallback, and cancel the swap
invoice when the server rejects the risk wait. Refresh selected
deposits before the legacy fallback so recovered monitors use current
confirmation heights.
2026-07-12 09:14:33 +02:00
Slyghtning
da96842264
notifications: fan out static loop-in risk decisions
Add cached per-swap notification fanout for static loop-in
confirmation-risk acceptance and rejection notifications so loop-in
FSMs can subscribe by swap hash and receive decisions that arrived
before subscription.
2026-07-12 09:14:33 +02:00
Slyghtning
ef78c85e88
staticaddr/loopin: cancel signing for unavailable deposits
Check the originally selected deposit outpoints before signing a static
loop-in HTLC transaction. If any selected outpoint is no longer
available, cancel the swap invoice and fail the signing action instead
of producing signatures for stale inputs.
2026-07-12 09:14:33 +02:00
Slyghtning
1d935c657f
loopd: filter static deposit views through active set
Use the deposit manager's visible-deposit view for normal list and
summary RPCs so historical Deposited rows whose outpoints vanished from
lnd's wallet view are not exposed as available funds.
2026-07-12 09:14:32 +02:00
Slyghtning
dc7da41b28
staticaddr: refresh deposits before spend selection
Refresh the active static-address deposit set against lnd's wallet view
before quote, loop-in, withdrawal, channel-open, and autoloop selection
paths. This prevents stale persisted Deposited records from being
selected after replacement, reorg, or an external spend.
2026-07-12 09:14:32 +02:00
Slyghtning
1c89ff83f1
staticaddr/loopin: account for autoloop deposit expiry
Use the shared deposit-expiry helper when building autoloop DP
candidates so unconfirmed deposits do not look like the
earliest-expiring options.

This keeps the no-change selector's expiry tie-break aligned with the
generic loop-in deposit selection rules.
2026-07-12 09:14:32 +02:00
Slyghtning
0223caa370
staticaddr/loopin: treat unconfirmed deposits as swappable
Static address deposits with no confirmation height have not started
their CSV timeout yet, so keep them eligible for loop-in selection
instead of treating them as already near expiry. Prefer confirmed
deposits before unconfirmed ones during automatic selection, and share
the remaining-lifetime calculation used by the selector.
2026-07-12 09:14:32 +02:00
Slyghtning
557ba99513
staticaddr: require confirmed deposits for withdraws and channel opens
Deposited can now include mempool outputs for static loop-ins, but
withdrawals and static channel opens still require confirmed funding
inputs. Filter automatic channel-open selection to confirmed deposits
and reject explicit unconfirmed selections, including withdraw-all
requests that would otherwise silently include mempool deposits.
2026-07-12 09:14:32 +02:00
Slyghtning
e8dd3aa009
staticaddr: expose tracked deposit availability
Build list and summary responses from tracked deposit records instead
of raw wallet UTXOs so RPC clients see the manager availability state.
Split unconfirmed value from confirmed deposited value in summaries,
and reject manual loop-in quotes for selected deposits that are not
currently Deposited.
2026-07-12 09:14:32 +02:00
Slyghtning
e4bcc94a36
staticaddr/deposit: reconcile active deposits with wallet
Treat lnd's wallet view as the source of spendable static-address
outpoints while keeping historical deposit records in the DB. Reconcile
active FSMs against the current wallet view, reactivate known deposits
that reappear, and hide stale Deposited records from the visible
deposit set.
2026-07-12 09:14:32 +02:00
Slyghtning
ac12d251f5
staticaddr/deposit: replay startup block after recovery
The first block epoch is consumed before recovered deposit FSMs exist.
Replay that startup height after recovery so already-expired deposits
can run expiry handling immediately after restart.
2026-07-12 09:14:31 +02:00
Slyghtning
1abe617991
staticaddr/deposit: track unconfirmed deposits
Retain static-address deposits as soon as lnd reports the UTXO, even
when the output is still unconfirmed. Store the first confirmation
height once the output confirms.

Derive confirmation heights from the current wallet view because lnd
reports confirmation counts instead of first-confirmation heights.
2026-07-12 09:14:31 +02:00
Slyghtning
12ebeabd3d
Merge pull request #1161 from hieblmi/dyn-conf-prep
Some checks failed
CI / RPC compilation check (push) Has been cancelled
CI / SQL compilation check (push) Has been cancelled
CI / go mod check (push) Has been cancelled
CI / build and lint code (push) Has been cancelled
CI / verify that auto-generated documentation is up-to-date (push) Has been cancelled
CI / run unit-test sqlite3 race (push) Has been cancelled
CI / run unit-test postgres race (push) Has been cancelled
CI / run LiT itests (push) Has been cancelled
CI / run LiT unit tests (push) Has been cancelled
staticaddr: harden deposit and loop-in lifecycle handling
2026-07-08 11:04:11 +02:00
Slyghtning
aed7df97a0
build: replace disappeared Go vanity modules 2026-07-08 10:42:19 +02:00
Slyghtning
c87273d32e
build: increase lint timeout 2026-07-08 09:02:12 +02:00
Slyghtning
814f046d8b
staticaddr/openchannel: fix nolint directive 2026-07-08 09:02:12 +02:00
Slyghtning
6582aa0807
staticaddr/loopin: check deposits before htlc signing
Before we send HTLC signatures to the server, the server cannot publish
the HTLC transaction. After those signatures are handed over, the server
can publish an HTLC that spends the selected deposits even if it never
pays the swap invoice.

Defend against stale local deposit state by checking the wallet's current
txout view immediately before signing. A deposit can have been spent by a
known withdrawal, channel open, timeout sweep, replacement, or another
wallet transaction while the loop-in FSM is recovering or while earlier
state still marked it as selected.

Failing before signing leaves the server without spend authority over an
unavailable input. Include mempool spends in the check so wallet-known
unconfirmed spends are treated as unavailable too.
2026-07-08 09:02:06 +02:00
Slyghtning
bd3882d5b0
staticaddr/loopin: use payment timeout duration helper 2026-07-08 09:01:18 +02:00
Slyghtning
3fdd9e2250
staticaddr/loopin: recover deposits by current outpoint
Recovered loop-ins carry two outpoint views. DepositOutpoints is the
immutable swap input snapshot sent to the server and used to validate
sweep requests. Deposits comes from the store's swap_hash/deposit-id
join and reflects the current deposit rows.

The active-deposit lookup takes a detour through the reconstructed
deposit rows before asking the deposit manager for active deposits.
That keeps recovery from depending on the historical input snapshot.

A future replacement path can RBF a deposit from its original funding
outpoint to a replacement outpoint while the swap still needs to retain
the original input list. Looking up active deposits by DepositOutpoints
would then fail recovery even though the store still maps the correct
deposit IDs to the swap hash.

Keep list responses on the store reconstruction too, so they do not
re-resolve deposits through historical outpoints.
2026-07-08 09:01:17 +02:00
Slyghtning
67252a84de
staticaddr/deposit: canonicalize multi-deposit locks 2026-07-08 09:01:17 +02:00
Slyghtning
814af6aadf
staticaddr/loopin: keep htlc monitor resumable
After the client gives the server HTLC signatures, shutdown must not drive the monitor state through the generic error path. That path cancels the invoice and attempts to unlock deposits even though the server can still publish the HTLC.

Return NoOp for monitor-state cancellation races and cover shutdown with a regression test that asserts no invoice cancellation or deposit unlock occurs.
2026-07-08 09:01:13 +02:00
Slyghtning
0c0cee377b
staticaddr/loopin: keep htlc timeout sweep resumable
A shutdown while publishing or monitoring the HTLC timeout sweep should not
transition the loop-in to Failed.

Return NoOp on context cancellation in those actions so the persisted
state remains a recovery point. Add focused tests for shutdown during
publication retry and confirmation monitoring.
2026-07-08 09:01:02 +02:00
Slyghtning
58fbe2230e
staticaddr/deposit: guard confirmation height access
Document deposit lock ownership for mutable confirmation state and
route production reads through deposit accessors.

Keep store persistence on no-lock helpers while callers hold the
deposit lock, preserving the existing transition behavior without
leaving direct field reads in user-facing paths.
2026-07-08 09:01:01 +02:00
Slyghtning
f468f24e6f
staticaddr/deposit: ignore queued expiry in final states
A block notification can queue OnExpiry before a deposit reaches a final
state. If the final transition wins that race first, the stale expiry event
must not overwrite the terminal outcome.

Keep LoopedIn and Withdrawn as self-loops on OnExpiry, matching the other
final states. Add a focused FSM test that sends OnExpiry directly to each
final state and verifies the state is preserved.
2026-07-08 09:01:01 +02:00
Slyghtning
d8b24d31c0
staticaddr/loopin: default payment timeout duration
Add a duration helper that falls back to the default payment timeout.

Recovered legacy swaps can have a zero persisted timeout, so later
deadline logic can use this without treating zero as immediate expiry.
2026-07-08 09:01:01 +02:00
Slyghtning
7f57f6fc6b
staticaddr/deposit: reject invalid transitions
Reject nil deposits and final-state deposits before sending FSM
events.

This keeps callers from transitioning stale or completed deposits and
uses the no-lock state helper while deposits are already locked.
2026-07-08 09:01:01 +02:00
Slyghtning
77d9335da2
staticaddr/deposit: serialize deposit reconciliation
Guard reconcileDeposits with a dedicated mutex.

Polling and block-driven reconciliation can overlap, so serialize the
path before it updates confirmation data and active FSM state.
2026-07-08 09:01:01 +02:00
Slyghtning
38dce3685f
staticaddr/deposit: factor active deposit notifications
Move active-deposit block notification fan-out into a helper.

This keeps the event loop small and gives later startup replay logic
a single path for notifying recovered deposit FSMs.
2026-07-08 09:01:01 +02:00
Slyghtning
6ce13ba8a4
staticaddr/deposit: document lock ordering
Document the lock-order invariant between Manager.mu and individual
deposit locks.

Later changes need both locks in the same path, so make the rule
explicit before the locking surface grows.
2026-07-08 09:01:00 +02:00
Slyghtning
f8e9d11d04
staticaddr/loopin: add lnd txout checker
Add a TxOutChecker interface for checking whether a selected deposit
outpoint is still available before signing the HTLC transaction.

Back the implementation with lnd wallet transaction data so known
confirmed and mempool spends mark the outpoint unavailable.
2026-07-08 09:00:56 +02:00
Slyghtning
508bf90a1c
staticaddr/loopin: preserve selected deposit outpoints
Store an independent snapshot of the outpoints selected for a
static loop-in.

Recovered swaps remain tied to the original funding outputs even if
deposit records later change confirmation or replacement metadata.

Avoid decoding an empty database outpoint string as a synthetic
outpoint.
2026-07-08 09:00:34 +02:00
Slyghtning
07d87c23a6
staticaddr/deposit: stop removed fsms
Add an explicit Stop method for deposit FSM block-notification
loops.

Call it when the manager removes a finalized active deposit so stale
FSM goroutines stop consuming block updates.
2026-07-08 09:00:26 +02:00
Slyghtning
8456314155
staticaddr/loopin: handle closed invoice updates
Treat closed invoice update channels as terminal for the monitor loop.

This avoids spinning when lnd closes the subscription after invoice cancellation or shutdown.
2026-07-08 09:00:26 +02:00
Slyghtning
a6d061c568
staticaddr/loopin: factor invoice update handling
Extract the monitor invoice update semantics into a helper and cover the existing state mapping with a dedicated test.
2026-07-08 09:00:26 +02:00
Slyghtning
ee5d84b323
staticaddr/deposit: reject duplicate outpoints
Reject duplicate static-address deposit outpoints before creating
withdrawal, loop-in, or channel-open requests.

Use the shared outpoint duplicate helper so each flow reports the
same input validation failure.
2026-07-08 09:00:26 +02:00
Slyghtning
0611832030
staticaddr/deposit: ignore expiry blocks in final states
Return early when block notifications reach deposits that already
moved into a terminal state.

This prevents final deposits from retrying expiry handling after
recovery or while their FSM is still draining block updates.
2026-07-08 09:00:26 +02:00
Slyghtning
ba1c37c0da
staticaddr/deposit: handle loop-in htlc timeout
Keep deposits locked when the server publishes the loop-in HTLC
without paying the invoice.

This lets the client sweep through the HTLC timeout path instead
of making the same outputs available for another action.
2026-07-08 09:00:25 +02:00