@@ -2,6 +2,7 @@ package sweepbatcher
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"sync"
7
8
"time"
@@ -46,36 +47,35 @@ const (
46
47
type BatcherStore interface {
47
48
// FetchUnconfirmedSweepBatches fetches all the batches from the
48
49
// database that are not in a confirmed state.
49
- FetchUnconfirmedSweepBatches (ctx context.Context ) ([]* dbBatch ,
50
- error )
50
+ FetchUnconfirmedSweepBatches (ctx context.Context ) ([]* dbBatch , error )
51
51
52
52
// InsertSweepBatch inserts a batch into the database, returning the id
53
53
// of the inserted batch.
54
- InsertSweepBatch (ctx context.Context ,
55
- batch * dbBatch ) (int32 , error )
54
+ InsertSweepBatch (ctx context.Context , batch * dbBatch ) (int32 , error )
55
+
56
+ // DropBatch drops a batch from the database. This should only be used
57
+ // when a batch is empty.
58
+ DropBatch (ctx context.Context , id int32 ) error
56
59
57
60
// UpdateSweepBatch updates a batch in the database.
58
- UpdateSweepBatch (ctx context.Context ,
59
- batch * dbBatch ) error
61
+ UpdateSweepBatch (ctx context.Context , batch * dbBatch ) error
60
62
61
63
// ConfirmBatch confirms a batch by setting its state to confirmed.
62
64
ConfirmBatch (ctx context.Context , id int32 ) error
63
65
64
66
// FetchBatchSweeps fetches all the sweeps that belong to a batch.
65
- FetchBatchSweeps (ctx context.Context ,
66
- id int32 ) ([]* dbSweep , error )
67
+ FetchBatchSweeps (ctx context.Context , id int32 ) ([]* dbSweep , error )
67
68
68
69
// UpsertSweep inserts a sweep into the database, or updates an existing
69
70
// sweep if it already exists.
70
71
UpsertSweep (ctx context.Context , sweep * dbSweep ) error
71
72
72
73
// GetSweepStatus returns the completed status of the sweep.
73
- GetSweepStatus (ctx context.Context , swapHash lntypes.Hash ) (
74
- bool , error )
74
+ GetSweepStatus (ctx context.Context , swapHash lntypes.Hash ) (bool , error )
75
75
76
76
// GetParentBatch returns the parent batch of a (completed) sweep.
77
- GetParentBatch (ctx context.Context , swapHash lntypes.Hash ) (
78
- * dbBatch , error )
77
+ GetParentBatch (ctx context.Context , swapHash lntypes.Hash ) (* dbBatch ,
78
+ error )
79
79
80
80
// TotalSweptAmount returns the total amount swept by a (confirmed)
81
81
// batch.
@@ -135,7 +135,7 @@ type SpendNotifier struct {
135
135
}
136
136
137
137
var (
138
- ErrBatcherShuttingDown = fmt . Errorf ("batcher shutting down" )
138
+ ErrBatcherShuttingDown = errors . New ("batcher shutting down" )
139
139
)
140
140
141
141
// Batcher is a system that is responsible for accepting sweep requests and
@@ -153,6 +153,10 @@ type Batcher struct {
153
153
// quit signals that the batch must stop.
154
154
quit chan struct {}
155
155
156
+ // initDone is a channel that is closed when the batcher has been
157
+ // initialized.
158
+ initDone chan struct {}
159
+
156
160
// wallet is the wallet kit client that is used by batches.
157
161
wallet lndclient.WalletKitClient
158
162
@@ -200,6 +204,7 @@ func NewBatcher(wallet lndclient.WalletKitClient,
200
204
sweepReqs : make (chan SweepRequest ),
201
205
errChan : make (chan error , 1 ),
202
206
quit : make (chan struct {}),
207
+ initDone : make (chan struct {}),
203
208
wallet : wallet ,
204
209
chainNotifier : chainNotifier ,
205
210
signerClient : signerClient ,
@@ -216,6 +221,7 @@ func (b *Batcher) Run(ctx context.Context) error {
216
221
runCtx , cancel := context .WithCancel (ctx )
217
222
defer func () {
218
223
cancel ()
224
+ close (b .quit )
219
225
220
226
for _ , batch := range b .batches {
221
227
batch .Wait ()
@@ -238,6 +244,9 @@ func (b *Batcher) Run(ctx context.Context) error {
238
244
}
239
245
}
240
246
247
+ // Signal that the batcher has been initialized.
248
+ close (b .initDone )
249
+
241
250
for {
242
251
select {
243
252
case sweepReq := <- b .sweepReqs :
@@ -306,7 +315,7 @@ func (b *Batcher) handleSweep(ctx context.Context, sweep *sweep,
306
315
307
316
if batch .sweepExists (sweep .swapHash ) {
308
317
accepted , err := batch .addSweep (ctx , sweep )
309
- if err != nil {
318
+ if err != nil && ! errors . Is ( err , ErrBatchShuttingDown ) {
310
319
return err
311
320
}
312
321
@@ -321,7 +330,7 @@ func (b *Batcher) handleSweep(ctx context.Context, sweep *sweep,
321
330
// If one of the batches accepts the sweep, we provide it to that batch.
322
331
for _ , batch := range b .batches {
323
332
accepted , err := batch .addSweep (ctx , sweep )
324
- if err != nil && err != ErrBatchShuttingDown {
333
+ if err != nil && ! errors . Is ( err , ErrBatchShuttingDown ) {
325
334
return err
326
335
}
327
336
@@ -379,6 +388,7 @@ func (b *Batcher) spinUpBatch(ctx context.Context) (*batch, error) {
379
388
verifySchnorrSig : b .VerifySchnorrSig ,
380
389
purger : b .AddSweep ,
381
390
store : b .store ,
391
+ quit : b .quit ,
382
392
}
383
393
384
394
batch := NewBatch (cfg , batchKit )
@@ -407,23 +417,23 @@ func (b *Batcher) spinUpBatch(ctx context.Context) (*batch, error) {
407
417
// spinUpBatchDB spins up a batch that already existed in storage, then
408
418
// returns it.
409
419
func (b * Batcher ) spinUpBatchFromDB (ctx context.Context , batch * batch ) error {
410
- cfg := batchConfig {
411
- maxTimeoutDistance : batch .cfg .maxTimeoutDistance ,
412
- batchConfTarget : defaultBatchConfTarget ,
413
- }
414
-
415
- rbfCache := rbfCache {
416
- LastHeight : batch .rbfCache .LastHeight ,
417
- FeeRate : batch .rbfCache .FeeRate ,
418
- }
419
-
420
420
dbSweeps , err := b .store .FetchBatchSweeps (ctx , batch .id )
421
421
if err != nil {
422
422
return err
423
423
}
424
424
425
425
if len (dbSweeps ) == 0 {
426
- return fmt .Errorf ("batch %d has no sweeps" , batch .id )
426
+ log .Infof ("skipping restored batch %d as it has no sweeps" ,
427
+ batch .id )
428
+
429
+ // It is safe to drop this empty batch as it has no sweeps.
430
+ err := b .store .DropBatch (ctx , batch .id )
431
+ if err != nil {
432
+ log .Warnf ("unable to drop empty batch %d: %v" ,
433
+ batch .id , err )
434
+ }
435
+
436
+ return nil
427
437
}
428
438
429
439
primarySweep := dbSweeps [0 ]
@@ -439,6 +449,11 @@ func (b *Batcher) spinUpBatchFromDB(ctx context.Context, batch *batch) error {
439
449
sweeps [sweep .swapHash ] = * sweep
440
450
}
441
451
452
+ rbfCache := rbfCache {
453
+ LastHeight : batch .rbfCache .LastHeight ,
454
+ FeeRate : batch .rbfCache .FeeRate ,
455
+ }
456
+
442
457
batchKit := batchKit {
443
458
id : batch .id ,
444
459
batchTxid : batch .batchTxid ,
@@ -456,6 +471,12 @@ func (b *Batcher) spinUpBatchFromDB(ctx context.Context, batch *batch) error {
456
471
purger : b .AddSweep ,
457
472
store : b .store ,
458
473
log : batchPrefixLogger (fmt .Sprintf ("%d" , batch .id )),
474
+ quit : b .quit ,
475
+ }
476
+
477
+ cfg := batchConfig {
478
+ maxTimeoutDistance : batch .cfg .maxTimeoutDistance ,
479
+ batchConfTarget : defaultBatchConfTarget ,
459
480
}
460
481
461
482
newBatch := NewBatchFromDB (cfg , batchKit )
0 commit comments