Commit graph

92 commits

Author SHA1 Message Date
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
Boris Nagaev
be69653bf0
sweepbatcher/store: remove unused field clock 2024-08-13 09:20:31 -03:00
Boris Nagaev
ce4a4d97a5
sweepbatcher: rename a private const
Renamed defaultPublishDelay to defaultTestnetPublishDelay. Its godoc was already
for defaultTestnetPublishDelay, but the const was named defaultPublishDelay.
2024-08-13 09:20:31 -03:00
Boris Nagaev
fa8703f052
swap: fix leaf estimation in AddSuccessToEstimator
According to AddTapscriptInput's godoc, the first argument (leafWitnessSize)
must include not the whole size of witness, but only the size of data consumed
by the revealed script. Previously the value was too high, because it also
included the following extra elements: number_of_witness_elements (1 byte),
witness script and its size, control block and its size.

Tests for greedy_batch_selection were affected by this change.
2024-08-12 12:18:36 -03:00
yingshanghuangqiao
57ebc3ff16 chore: fix some comments
Signed-off-by: yingshanghuangqiao <yingshanghuangqiao@foxmail.com>
2024-07-22 16:11:16 +08:00
crystalstall
27a234db66 chore: fix some comments for struct field
Signed-off-by: crystalstall <crystalruby@qq.com>
2024-07-19 14:20:07 +08:00
Boris Nagaev
026cf0d47a
sweepbatcher: always try greedy batch selection
Now that sweep.minFeeRate is always set, greedy batch selection has all needed
inputs to work even without customFeeRate provider.
2024-07-18 13:38:57 -03:00
Boris Nagaev
75641c3573
sweepbatcher: always fill sweep.minFeeRate
Use customFeeRate if it is provided, otherwise use wallet's EstimateFeeRate.

Added flag SkipNextBump to rbfCache to avoid extra bumping upon updating
fee rate externally.

Fix test TestSweepBatcherCloseDuringAdding, it didn't have confTarget and
failed in wallet.EstimateFeeRate call.
2024-07-18 13:38:57 -03:00
Boris Nagaev
f5e97c035d
sweepbatcher: log batcher failures
This is useful to debug. It used to fail silently.
2024-07-18 13:38:57 -03:00
Boris Nagaev
db5e0d1d27
sweepbatcher: fix inaccuracies in fee estimations
Use SigHashDefault instead of SigHashAll in weight estimations.
Actual code uses SigHashDefault, not SigHashAll. SigHashAll is 1wu larger.

Use the actual destination address in weight estimator, not taproot always.
In the test the type of address is P2WPKH, not taproot.

Updated testSweepFetcher to calculate fee, fee rate and weight accurately and
to compare the data observed in the published transaction with the estimates.
2024-07-18 13:38:57 -03:00
Boris Nagaev
44d9147175
sweepbatcher: add greedy batch selection algorithm
If custom fee rates are used, the algorithm is tried. It selects a batch for the
sweep using the greedy algorithm, which minimizes costs, and adds the sweep to
the batch. If it fails, old algorithm is used, trying to add to any batch, or
starting a new batch.
2024-07-18 13:38:57 -03:00
Boris Nagaev
e8141578ac
sweepbatcher: MinFeeRate -> WithCustomFeeRate
The reason is because we want to know in advance if fee rates come from
an external source or are determined by sweepbatcher internally.

Also remove WithNoBumping option. It is now a part of WithCustomFeeRate:
if WithCustomFeeRate is passed, automatic fee bumping by sweepbatcher
is disabled.
2024-07-18 13:38:57 -03:00
Boris Nagaev
ccd1b312ca
sweepbatcher: fix copy-paste with batch kit 2024-07-18 13:38:57 -03:00
Boris Nagaev
1f1a27447c
sweepbatcher: fix copy-paste with batchConfig 2024-07-18 13:38:57 -03:00
Boris Nagaev
1290ebe535
sweepbatcher: fix copy-paste in sweep creation 2024-07-18 13:38:57 -03:00
Andras Banki-Horvath
6a4ef3683a
sweepbatcher: fix spawning condition "unattached" spend notifiers
Previously, when handling a sweep we assumed that if a sweep status
was completed, the parent batch was also finished. However, since the
batch confirmation status depends on three on-chain confirmations, it
is possible that a spend notifier was started for a sweep of an active
batch. The notifier would fetch the parent batch from the database, but
because we incorrectly assumed that  the parent was confirmed (when it
was not), the DB call would fail with a 'no rows returned' error.
This failure would cause the sweep to fail and the sweep batcher to
stop, resulting in a permanent failure state.
2024-07-11 13:15:39 +02:00