Commit graph

107 commits

Author SHA1 Message Date
Boris Nagaev
7edbfeadd8
sweepbatcher: store batch status before monitoring
If monitorConfirmations fails, we still want to persist the state to DB.
2025-06-12 12:32:09 -03:00
Boris Nagaev
fa1bc48a68
sweepbatcher: remove unneeded for loops
The loop always had exactly one iteration.
2025-06-12 12:31:58 -03:00
Boris Nagaev
01664ad635
sweepbatcher: cancel spendCtx after processing
Function monitorSpendAndNotify used to cancel the context passed to
RegisterSpendNtfn right after starting the goroutine processing results.
Spend notifications were missed.

Now the context is canceled when the goroutine finishes.
2025-06-11 10:34:22 -03:00
Boris Nagaev
cb7c31c1b9
sweepbatcher: fix mistake in batch reading from DB 2025-06-11 10:34:22 -03:00
Boris Nagaev
c036c2adbd
sweepbatcher: fix mock TotalSweptAmount
Forgot to return the calculated total value.
2025-06-11 10:34:22 -03:00
Boris Nagaev
39f859a046
sweepbatcher: send spend error to notifier 2025-06-11 10:34:22 -03:00
Boris Nagaev
501faa8375
sweepbatcher: unblock sending if notifier quits 2025-06-11 10:34:22 -03:00
Boris Nagaev
6a32b46132
sweepbatcher: mark channels receive- or send-only 2025-06-11 10:34:22 -03:00
Boris Nagaev
b9b256f4b3
sweepbatcher: add mode with presigned transactions
In this mode sweepbatcher uses transactions provided by the Presigned helper.
Transactions are signed upon adding an input to a batch.

A single Batcher instance can handle both presigned and regular batches.
Currently presigned and non-presigned sweeps never appear in the same batch.
2025-05-08 17:24:10 -03:00
Boris Nagaev
a4a2bfbee3
sweepbatcher: use WithoutCancel for notifications 2025-05-08 17:24:10 -03:00
Boris Nagaev
bb837a4aec
sweepbatcher: load sweeps in AddSweep
This is needed to run additional checks in AddSweep in the next commit.
2025-05-08 17:24:10 -03:00
Boris Nagaev
78ca6bd069
sweepbatcher: rm unused field batchKit.returnChan 2025-05-08 17:24:10 -03:00
Boris Nagaev
b7d3bc46f8
sweepbatcher: auto-increment sweep.ID in StoreMock 2025-05-08 17:24:10 -03:00
Boris Nagaev
149bffcad7
sweepbatcher: fix rounding in constructUnsignedTx
Previously it may round one satoshi towards zero resulting in fee-rate
slightly lower than requested.
2025-05-08 17:24:10 -03:00
Boris Nagaev
1983cc2d80
sweepbatcher: make func constructUnsignedTx pure
Also added a unit test for it.
2025-05-08 17:24:10 -03:00
Boris Nagaev
4c26aefe80
sweepbatcher: fix height hint for confirmations
Previously, we passed the current best block height as the height hint to
RegisterConfirmationsNtfn. If Loop was shut down when a sweep was confirmed
and restarted later, it would use the current best height as the hint. This
caused the confirmation to be missed, since it had already occurred before
that height.

This commit fixes the issue by passing the initiation height of the swap as the
height hint instead. This is consistent with what we do in other places where
we use RegisterConfirmationsNtfn.

Since LND caches previously passed height hints for RegisterConfirmationsNtfn
and uses maximum passed value, to actually recover in such a condition, one has
to restart LND passing the option --height-hint-cache-query-disable and then
restart Loop applying this fix. If a pruned bitcoind backend is used, this might
not work.
2025-04-05 18:01:16 -03:00
Boris Nagaev
e8cf6386cc
sweepbatcher: allow adding groups of inputs
A group of inputs can be added by passing it in SweepRequest.Inputs field.
All the inputs belong to the same swap and are added to the same batch.
2025-04-03 09:49:46 -03:00
Boris Nagaev
472bec0be5
sweepbatcher: customize initialDelay per sweep
Option WithInitialDelay now accepts a function returning initialDelay
depending on sweep's data.

This is needed to be able to wait longer for sweeps with low priority, but
still sweeping high priority sweeps soon.
2025-04-03 09:22:58 -03:00
Boris Nagaev
c80ebb96e9
sweepbatcher: allow swap_hash to be non-unique
SwapHash used to be a key in the sweeps table. Now the key is outpoint which
replaces columns outpoint_txid and outpoint_index. In-memory structures and unit
tests were also updated to use outpoint as key. Outpoint is truly unique.
2025-04-01 11:11:44 -03:00
Boris Nagaev
90e36b5b71
sweepbatcher: add more details to errors
This is useful to debug errors from logs, to follow error propagation path.
2025-03-21 10:58:07 -03:00
Oliver Gugger
65251e8821
multi: update linter, fix issues 2025-03-10 22:59:50 +01:00
Oliver Gugger
722ad8839d
multi: update lnd compile-time dependency to v0.19.0 2025-03-10 22:59:49 +01:00
Boris Nagaev
a333031bf9
sweepbatcher: fix race conditions in UseLogger 2025-03-04 13:45:08 -03:00
Boris Nagaev
a2cee86783
sweepbatcher/test: fix races in require.Eventually
The code inside require.Eventually runs in parallel with the event loops
of the batcher and its batches. Accessing fields of the batcher and batches
must be done within an event loop.

To address this, testRunInEventLoop methods were added to the Batcher and batch
types. Unit tests were then rewritten to use this approach when accessing
batcher and batch fields.

Additionally, in many cases, receive operations from RegisterSpendChannel
were moved before require.Eventually. This prevents testRunInEventLoop from
getting stuck in an event loop while blocked on a RegisterSpendChannel send
operation.
2025-03-04 13:45:03 -03:00
Boris Nagaev
026890a1ea
sweepbatcher/test: protect mock data with mutex
Several structures were accessed without protection causing crashes under -race.
2025-03-04 12:57:27 -03:00
Boris Nagaev
ab59bdafd2
sweepbatcher: replace batch logger atomically
This is needed to fix crashes in unit tests under -race.
2025-03-04 12:56:54 -03:00
Boris Nagaev
a0f87241da
sweepbatcher: remove all completed batches
Previously, if a completed batch was visited after a batch to which the
sweep was added, it was not deleted because the function returned early.

This has been separated into two loops: the first one removes completed batches,
and the second one adds the sweep to a batch.
2025-03-04 11:17:39 -03:00
Boris Nagaev
a64f4610ab
sweepbatcher: fix usage of EventuallyWithT
It should use the c variable passed into the lambda, not the parent t.
It should use assert, not require package.
2025-03-04 10:25:30 -03:00
Boris Nagaev
f0f64f83c3
sweepbatcher: fix race in store_mock 2025-03-04 10:25:30 -03:00
Boris Nagaev
2c38de121c
sweepbatcher: always enabled mixed batches
Mixed batches approach covers the case where all the inputs are cooperative
(function publishBatchCoop) and it is better than fully non-cooperative case
(function publishBatch), but it can also create such transaction if needed, i.e.
if all the sweeps are non-cooperative. So we can remove functions publishBatch,
publishBatchCoop, option WithMixedBatch and associated code in greedy batch
selection algorithm.
2025-02-05 15:16:57 -03:00
Boris Nagaev
6efd010014
sweepbatcher: run batch with currentHeight set
Prevent a crash with "a height hint greater than 0 must be provided" error when
monitorSpend starts at the beginning of batch.Run.

The timer timerChan is now initialized at the start, because it was previously
initialized after the first block (the current tip) was read from blockChan and
now the first block is read before the main for-select loop to fill the field
currentHeight in advance.
2025-01-17 12:39:31 -03:00
Boris Nagaev
89fbf9a5cf
sweepbatcher: rm unused field batch.blockEpochChan 2025-01-17 12:39:31 -03:00
Boris Nagaev
06ed714e9a
sweepbatcher: check that spending tx has an output
Previously the code handling spending tx crashed if it doesn't have an output.
This is likely to occur only in tests.
2025-01-17 12:39:24 -03:00
Boris Nagaev
864d7f24cd
sweepbatcher: make sure feerate does not decrease
Previous behaviour was to overwrite batch's feerate with minFeeRate of
its primary sweep, which could be lower that previus batch's feerate or
lower that feerate of some other sweep.

Instead, batch's feerate only grows and never declines and is at least as high
as the highest feerate of its sweeps.

Added a test to verify this.
2024-10-15 11:28:40 -03:00
Slyghtning
3ee3963030
sweepbatcher: log confirmed batch tx id 2024-09-02 15:42:51 +02:00
Boris Nagaev
dba3d15b02
sweepbatcher: fix typo in log message 2024-09-01 13:00:36 -03:00
Boris Nagaev
7c93dff830
sweepbatcher: add option WithPublishErrorHandler
WithPublishErrorHandler sets the callback used to handle publish errors.
It can be used to filter out noisy messages.
2024-08-27 19:26:29 -03:00
Boris Nagaev
898efbf2ae
sweepbatcher: fix godoc 2024-08-27 10:57:41 -03:00
Boris Nagaev
7780aca492
sweepbatcher: log the reason of acceptance failure
Add Info log message in cases when addSweep returns accept=false and err=nil.
2024-08-26 20:53:29 -03:00
Boris Nagaev
f21a21ee41
sweepbatcher: set max batch size to 1000 sweeps
This is needed to avoid non-standard batch transactions (larger than 400k wu).
A non-cooperative input is 393 wu, so 1000 inputs are still under 400k wu.
2024-08-26 14:17:24 -03:00
Boris Nagaev
b171f76b27
sweepbatcher: make greedy algo mixed batch aware 2024-08-21 14:05:50 -03:00
Boris Nagaev
d007cf6e20
sweepbatcher: use coopFailed in greedy selection
Treat coopFailed flag the same as nonCoopHint. The former is what we found in
previos signing attempts, the later is what the caller signalled to us.
2024-08-21 14:05:50 -03:00
Boris Nagaev
26eda00ef2
sweepbatcher: add mixed batches option
Option WithMixedBatch instructs sweepbatcher to create mixed batches with regard
to cooperativeness. Such a batch can include both sweeps signed both
cooperatively and non-cooperatively. If cooperative signing fails for a sweep,
transaction is updated to sign that sweep non-cooperatively and another round of
cooperative signing runs on the remaining sweeps. The remaining sweeps are
signed in non-cooperative (more expensive) way. If the whole procedure fails for
whatever reason, the batch is signed non-cooperatively (the fallback).
2024-08-21 14:05:50 -03:00
Boris Nagaev
2c2c427a6d
sweepbatcher: factor out method createPsbt
Unload method publishBatchCoop. Also this code will be reused in new method
for mixed batches soon.
2024-08-21 14:05:50 -03:00
Boris Nagaev
5cd6c0c83c
sweepbatcher: coopSignBatchTx accepts wire.MsgTx
... instead of psbt.Packet.

Make the code simpler. Function worked with packet.UnsignedTx only,
so it is easier to pass tx directly.
2024-08-21 14:05:50 -03:00
Boris Nagaev
7fb7c2bda1
sweepbatcher: customize transaction labels
Previously sweepbatcher used loop/labels.LoopOutBatchSweepSuccess to assign
transactions labels. The value is "BatchOutSweepSuccess -- $batch_id", which
does not fit use cases outside of loop-out. Now there is option WithTxLabeler
which sets a function used to generate the label.
2024-08-13 10:42:00 -03:00
Boris Nagaev
9af6718089
sweepbatcher: test InitialDelay and PublishDelay
Tested scenarios:

1. For a regular sweep newly added it waits for initialDelay + publishDelay
   before publishing a transaction.
2. For a sweep recovered from DB it does not wait before publishing tx.
3. If a sweep is about to expire, initialDelay is skipped.
2024-08-13 10:28:11 -03:00
Boris Nagaev
3f56345492
sweepbatcher: add option WithPublishDelay
WithPublishDelay sets the delay of batch publishing that is applied in the
beginning, after the appearance of a new block in the network or after the
end of initial delay (see WithInitialDelay). It is needed to prevent
unnecessary transaction publishments when a spend is detected on that block.
Default value depends on the network: 5 seconds in mainnet, 0.5s in testnet.
For batches recovered from DB this value is always 0s.
2024-08-13 09:20:31 -03:00
Boris Nagaev
e178d32717
sweepbatcher: add option WithInitialDelay
WithInitialDelay instructs sweepbatcher to wait for the duration provided
after new batch creation before it is first published. This facilitates
better grouping. It only affects newly created batches, not batches loaded from
DB, so publishing does happen in case of a daemon restart (especially important
in case of a crashloop). Defaults to 0s. If a sweep is about to expire (time
until timeout is less that 2x initialDelay), then waiting is skipped.
2024-08-13 09:20:31 -03:00
Boris Nagaev
429eb85e14
sweepbatcher: use lnd/clock for timers
Added option: WithClock. Use it for publishDelay timer.
It will be used for testing.
2024-08-13 09:20:31 -03:00