@@ -2,6 +2,7 @@ package sweepbatcher
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "sync"
78 "time"
@@ -46,36 +47,35 @@ const (
4647type BatcherStore interface {
4748 // FetchUnconfirmedSweepBatches fetches all the batches from the
4849 // database that are not in a confirmed state.
49- FetchUnconfirmedSweepBatches (ctx context.Context ) ([]* dbBatch ,
50- error )
50+ FetchUnconfirmedSweepBatches (ctx context.Context ) ([]* dbBatch , error )
5151
5252 // InsertSweepBatch inserts a batch into the database, returning the id
5353 // 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
5659
5760 // UpdateSweepBatch updates a batch in the database.
58- UpdateSweepBatch (ctx context.Context ,
59- batch * dbBatch ) error
61+ UpdateSweepBatch (ctx context.Context , batch * dbBatch ) error
6062
6163 // ConfirmBatch confirms a batch by setting its state to confirmed.
6264 ConfirmBatch (ctx context.Context , id int32 ) error
6365
6466 // 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 )
6768
6869 // UpsertSweep inserts a sweep into the database, or updates an existing
6970 // sweep if it already exists.
7071 UpsertSweep (ctx context.Context , sweep * dbSweep ) error
7172
7273 // 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 )
7575
7676 // 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 )
7979
8080 // TotalSweptAmount returns the total amount swept by a (confirmed)
8181 // batch.
@@ -135,7 +135,7 @@ type SpendNotifier struct {
135135}
136136
137137var (
138- ErrBatcherShuttingDown = fmt . Errorf ("batcher shutting down" )
138+ ErrBatcherShuttingDown = errors . New ("batcher shutting down" )
139139)
140140
141141// Batcher is a system that is responsible for accepting sweep requests and
@@ -153,6 +153,10 @@ type Batcher struct {
153153 // quit signals that the batch must stop.
154154 quit chan struct {}
155155
156+ // initDone is a channel that is closed when the batcher has been
157+ // initialized.
158+ initDone chan struct {}
159+
156160 // wallet is the wallet kit client that is used by batches.
157161 wallet lndclient.WalletKitClient
158162
@@ -200,6 +204,7 @@ func NewBatcher(wallet lndclient.WalletKitClient,
200204 sweepReqs : make (chan SweepRequest ),
201205 errChan : make (chan error , 1 ),
202206 quit : make (chan struct {}),
207+ initDone : make (chan struct {}),
203208 wallet : wallet ,
204209 chainNotifier : chainNotifier ,
205210 signerClient : signerClient ,
@@ -216,6 +221,7 @@ func (b *Batcher) Run(ctx context.Context) error {
216221 runCtx , cancel := context .WithCancel (ctx )
217222 defer func () {
218223 cancel ()
224+ close (b .quit )
219225
220226 for _ , batch := range b .batches {
221227 batch .Wait ()
@@ -238,6 +244,9 @@ func (b *Batcher) Run(ctx context.Context) error {
238244 }
239245 }
240246
247+ // Signal that the batcher has been initialized.
248+ close (b .initDone )
249+
241250 for {
242251 select {
243252 case sweepReq := <- b .sweepReqs :
@@ -306,7 +315,7 @@ func (b *Batcher) handleSweep(ctx context.Context, sweep *sweep,
306315
307316 if batch .sweepExists (sweep .swapHash ) {
308317 accepted , err := batch .addSweep (ctx , sweep )
309- if err != nil {
318+ if err != nil && ! errors . Is ( err , ErrBatchShuttingDown ) {
310319 return err
311320 }
312321
@@ -321,7 +330,7 @@ func (b *Batcher) handleSweep(ctx context.Context, sweep *sweep,
321330 // If one of the batches accepts the sweep, we provide it to that batch.
322331 for _ , batch := range b .batches {
323332 accepted , err := batch .addSweep (ctx , sweep )
324- if err != nil && err != ErrBatchShuttingDown {
333+ if err != nil && ! errors . Is ( err , ErrBatchShuttingDown ) {
325334 return err
326335 }
327336
@@ -379,6 +388,7 @@ func (b *Batcher) spinUpBatch(ctx context.Context) (*batch, error) {
379388 verifySchnorrSig : b .VerifySchnorrSig ,
380389 purger : b .AddSweep ,
381390 store : b .store ,
391+ quit : b .quit ,
382392 }
383393
384394 batch := NewBatch (cfg , batchKit )
@@ -407,23 +417,23 @@ func (b *Batcher) spinUpBatch(ctx context.Context) (*batch, error) {
407417// spinUpBatchDB spins up a batch that already existed in storage, then
408418// returns it.
409419func (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-
420420 dbSweeps , err := b .store .FetchBatchSweeps (ctx , batch .id )
421421 if err != nil {
422422 return err
423423 }
424424
425425 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
427437 }
428438
429439 primarySweep := dbSweeps [0 ]
@@ -439,6 +449,11 @@ func (b *Batcher) spinUpBatchFromDB(ctx context.Context, batch *batch) error {
439449 sweeps [sweep .swapHash ] = * sweep
440450 }
441451
452+ rbfCache := rbfCache {
453+ LastHeight : batch .rbfCache .LastHeight ,
454+ FeeRate : batch .rbfCache .FeeRate ,
455+ }
456+
442457 batchKit := batchKit {
443458 id : batch .id ,
444459 batchTxid : batch .batchTxid ,
@@ -456,6 +471,12 @@ func (b *Batcher) spinUpBatchFromDB(ctx context.Context, batch *batch) error {
456471 purger : b .AddSweep ,
457472 store : b .store ,
458473 log : batchPrefixLogger (fmt .Sprintf ("%d" , batch .id )),
474+ quit : b .quit ,
475+ }
476+
477+ cfg := batchConfig {
478+ maxTimeoutDistance : batch .cfg .maxTimeoutDistance ,
479+ batchConfTarget : defaultBatchConfTarget ,
459480 }
460481
461482 newBatch := NewBatchFromDB (cfg , batchKit )
0 commit comments