Skip to content

Commit df06885

Browse files
committed
sweepbatcher: test that empty batches won't prevent startup
1 parent 7ccba45 commit df06885

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

sweepbatcher/sweep_batcher.go

+8
Original file line numberDiff line numberDiff line change
@@ -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,
@@ -239,6 +244,9 @@ func (b *Batcher) Run(ctx context.Context) error {
239244
}
240245
}
241246

247+
// Signal that the batcher has been initialized.
248+
close(b.initDone)
249+
242250
for {
243251
select {
244252
case sweepReq := <-b.sweepReqs:

sweepbatcher/sweep_batcher_test.go

+83
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sweepbatcher
33
import (
44
"context"
55
"errors"
6+
"sync"
67
"testing"
78
"time"
89

@@ -1028,3 +1029,85 @@ func TestGetFeePortionForSweep(t *testing.T) {
10281029
})
10291030
}
10301031
}
1032+
1033+
// TestRestoringEmptyBatch tests that the batcher can be restored with an empty
1034+
// batch.
1035+
func TestRestoringEmptyBatch(t *testing.T) {
1036+
defer test.Guard(t)()
1037+
1038+
lnd := test.NewMockLnd()
1039+
ctx, cancel := context.WithCancel(context.Background())
1040+
1041+
store := loopdb.NewStoreMock(t)
1042+
1043+
batcherStore := NewStoreMock()
1044+
_, err := batcherStore.InsertSweepBatch(ctx, &dbBatch{})
1045+
require.NoError(t, err)
1046+
1047+
batcher := NewBatcher(lnd.WalletKit, lnd.ChainNotifier, lnd.Signer,
1048+
testMuSig2SignSweep, nil, lnd.ChainParams, batcherStore, store)
1049+
1050+
var wg sync.WaitGroup
1051+
wg.Add(1)
1052+
1053+
var runErr error
1054+
go func() {
1055+
defer wg.Done()
1056+
runErr = batcher.Run(ctx)
1057+
}()
1058+
1059+
// Wait for the batcher to be initialized.
1060+
<-batcher.initDone
1061+
1062+
// Create a sweep request.
1063+
sweepReq := SweepRequest{
1064+
SwapHash: lntypes.Hash{1, 1, 1},
1065+
Value: 111,
1066+
Outpoint: wire.OutPoint{
1067+
Hash: chainhash.Hash{1, 1},
1068+
Index: 1,
1069+
},
1070+
Notifier: &dummyNotifier,
1071+
}
1072+
1073+
swap := &loopdb.LoopOutContract{
1074+
SwapContract: loopdb.SwapContract{
1075+
CltvExpiry: 111,
1076+
AmountRequested: 111,
1077+
},
1078+
1079+
SwapInvoice: swapInvoice,
1080+
}
1081+
1082+
err = store.CreateLoopOut(ctx, sweepReq.SwapHash, swap)
1083+
require.NoError(t, err)
1084+
store.AssertLoopOutStored()
1085+
1086+
// Deliver sweep request to batcher.
1087+
batcher.sweepReqs <- sweepReq
1088+
1089+
// Since a batch was created we check that it registered for its primary
1090+
// sweep's spend.
1091+
<-lnd.RegisterSpendChannel
1092+
1093+
// Once batcher receives sweep request it will eventually spin up a
1094+
// batch.
1095+
require.Eventually(t, func() bool {
1096+
// Make sure that the sweep was stored and we have exactly one
1097+
// active batch.
1098+
return batcherStore.AssertSweepStored(sweepReq.SwapHash) &&
1099+
len(batcher.batches) == 1
1100+
}, test.Timeout, eventuallyCheckFrequency)
1101+
1102+
// Make sure we have only one batch stored (as we dropped the dormant
1103+
// one).
1104+
batches, err := batcherStore.FetchUnconfirmedSweepBatches(ctx)
1105+
require.NoError(t, err)
1106+
require.Len(t, batches, 1)
1107+
1108+
// Now make it quit by canceling the context.
1109+
cancel()
1110+
wg.Wait()
1111+
1112+
checkBatcherError(t, runErr)
1113+
}

0 commit comments

Comments
 (0)