Skip to content

Commit 980c7d4

Browse files
committed
sweepbatcher: align dbBatch type with DB schema
Previously, dbBatch had a State field (enum: Open, Closed, Confirmed), but in the database it is represented as a boolean Confirmed. The Closed state was stored the same way as Open. This wasn't an issue in practice, since an Open batch is quickly transitioned to Closed after startup. However, the in-memory mock stores plain dbBatch instances, leading to inconsistent behavior between the mock and the real DB-backed store. This commit updates dbBatch to match the database representation by replacing the State field with a Confirmed boolean.
1 parent 7edbfea commit 980c7d4

File tree

4 files changed

+29
-62
lines changed

4 files changed

+29
-62
lines changed

sweepbatcher/store.go

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ type dbBatch struct {
213213
// ID is the unique identifier of the batch.
214214
ID int32
215215

216-
// State is the current state of the batch.
217-
State string
216+
// Confirmed is set when the batch is fully confirmed.
217+
Confirmed bool
218218

219219
// BatchTxid is the txid of the batch transaction.
220220
BatchTxid chainhash.Hash
@@ -255,11 +255,8 @@ type dbSweep struct {
255255
// convertBatchRow converts a batch row from db to a sweepbatcher.Batch struct.
256256
func convertBatchRow(row sqlc.SweepBatch) *dbBatch {
257257
batch := dbBatch{
258-
ID: row.ID,
259-
}
260-
261-
if row.Confirmed {
262-
batch.State = batchConfirmed
258+
ID: row.ID,
259+
Confirmed: row.Confirmed,
263260
}
264261

265262
if row.BatchTxID.Valid {
@@ -288,7 +285,7 @@ func convertBatchRow(row sqlc.SweepBatch) *dbBatch {
288285
// it into the database.
289286
func batchToInsertArgs(batch dbBatch) sqlc.InsertBatchParams {
290287
args := sqlc.InsertBatchParams{
291-
Confirmed: false,
288+
Confirmed: batch.Confirmed,
292289
BatchTxID: sql.NullString{
293290
Valid: true,
294291
String: batch.BatchTxid.String(),
@@ -305,10 +302,6 @@ func batchToInsertArgs(batch dbBatch) sqlc.InsertBatchParams {
305302
MaxTimeoutDistance: batch.MaxTimeoutDistance,
306303
}
307304

308-
if batch.State == batchConfirmed {
309-
args.Confirmed = true
310-
}
311-
312305
return args
313306
}
314307

@@ -317,7 +310,7 @@ func batchToInsertArgs(batch dbBatch) sqlc.InsertBatchParams {
317310
func batchToUpdateArgs(batch dbBatch) sqlc.UpdateBatchParams {
318311
args := sqlc.UpdateBatchParams{
319312
ID: batch.ID,
320-
Confirmed: false,
313+
Confirmed: batch.Confirmed,
321314
BatchTxID: sql.NullString{
322315
Valid: true,
323316
String: batch.BatchTxid.String(),
@@ -333,10 +326,6 @@ func batchToUpdateArgs(batch dbBatch) sqlc.UpdateBatchParams {
333326
},
334327
}
335328

336-
if batch.State == batchConfirmed {
337-
args.Confirmed = true
338-
}
339-
340329
return args
341330
}
342331

sweepbatcher/store_mock.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (s *StoreMock) FetchUnconfirmedSweepBatches(ctx context.Context) (
3636

3737
result := []*dbBatch{}
3838
for _, batch := range s.batches {
39-
if batch.State != "confirmed" {
39+
if !batch.Confirmed {
4040
result = append(result, &batch)
4141
}
4242
}
@@ -91,7 +91,7 @@ func (s *StoreMock) ConfirmBatch(ctx context.Context, id int32) error {
9191
return errors.New("batch not found")
9292
}
9393

94-
batch.State = "confirmed"
94+
batch.Confirmed = true
9595
s.batches[batch.ID] = batch
9696

9797
return nil
@@ -201,7 +201,7 @@ func (s *StoreMock) TotalSweptAmount(ctx context.Context, batchID int32) (
201201
return 0, errors.New("batch not found")
202202
}
203203

204-
if batch.State != batchConfirmed && batch.State != batchClosed {
204+
if !batch.Confirmed {
205205
return 0, nil
206206
}
207207

sweepbatcher/sweep_batch.go

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ const (
135135
Open batchState = 0
136136

137137
// Closed is the state in which the batch is no longer able to accept
138-
// new sweeps.
138+
// new sweeps. NOTE: this state exists only in-memory. In the database
139+
// it is stored as Open and converted to Closed after a spend
140+
// notification arrives (quickly after start of Batch.Run).
139141
Closed batchState = 1
140142

141143
// Confirmed is the state in which the batch transaction has reached the
@@ -870,8 +872,8 @@ func (b *batch) Run(ctx context.Context) error {
870872
// completes.
871873
timerChan := clock.TickAfter(b.cfg.batchPublishDelay)
872874

873-
b.Infof("started, primary %s, total sweeps %d",
874-
b.primarySweepID, len(b.sweeps))
875+
b.Infof("started, primary %s, total sweeps %d, state: %d",
876+
b.primarySweepID, len(b.sweeps), b.state)
875877

876878
for {
877879
// If the batch is not empty, find earliest initialDelay.
@@ -2179,7 +2181,7 @@ func (b *batch) persist(ctx context.Context) error {
21792181
bch := &dbBatch{}
21802182

21812183
bch.ID = b.id
2182-
bch.State = stateEnumToString(b.state)
2184+
bch.Confirmed = b.state == Confirmed
21832185

21842186
if b.batchTxid != nil {
21852187
bch.BatchTxid = *b.batchTxid
@@ -2238,7 +2240,7 @@ func (b *batch) getBatchDestAddr(ctx context.Context) (btcutil.Address, error) {
22382240

22392241
func (b *batch) insertAndAcquireID(ctx context.Context) (int32, error) {
22402242
bch := &dbBatch{}
2241-
bch.State = stateEnumToString(b.state)
2243+
bch.Confirmed = b.state == Confirmed
22422244
bch.MaxTimeoutDistance = b.cfg.maxTimeoutDistance
22432245

22442246
id, err := b.store.InsertSweepBatch(ctx, bch)
@@ -2339,18 +2341,3 @@ func clampBatchFee(fee btcutil.Amount,
23392341

23402342
return fee
23412343
}
2342-
2343-
func stateEnumToString(state batchState) string {
2344-
switch state {
2345-
case Open:
2346-
return batchOpen
2347-
2348-
case Closed:
2349-
return batchClosed
2350-
2351-
case Confirmed:
2352-
return batchConfirmed
2353-
}
2354-
2355-
return ""
2356-
}

sweepbatcher/sweep_batcher.go

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,6 @@ const (
3131
// of sweeps that can appear in the same batch.
3232
defaultMaxTimeoutDistance = 288
3333

34-
// batchOpen is the string representation of the state of a batch that
35-
// is open.
36-
batchOpen = "open"
37-
38-
// batchClosed is the string representation of the state of a batch
39-
// that is closed.
40-
batchClosed = "closed"
41-
42-
// batchConfirmed is the string representation of the state of a batch
43-
// that is confirmed.
44-
batchConfirmed = "confirmed"
45-
4634
// defaultMainnetPublishDelay is the default publish delay that is used
4735
// for mainnet.
4836
defaultMainnetPublishDelay = 5 * time.Second
@@ -760,7 +748,7 @@ func (b *Batcher) AddSweep(ctx context.Context, sweepReq *SweepRequest) error {
760748
"sweep %x: %w", sweep.swapHash[:6], err)
761749
}
762750

763-
if parentBatch.State == batchConfirmed {
751+
if parentBatch.Confirmed {
764752
fullyConfirmed = true
765753
}
766754
}
@@ -844,7 +832,7 @@ func (b *Batcher) handleSweeps(ctx context.Context, sweeps []*sweep,
844832
if completed && *notifier != (SpendNotifier{}) {
845833
// The parent batch is indeed confirmed, meaning it is complete
846834
// and we won't be able to attach this sweep to it.
847-
if parentBatch.State == batchConfirmed {
835+
if parentBatch.Confirmed {
848836
return b.monitorSpendAndNotify(
849837
ctx, sweep, parentBatch.ID, notifier,
850838
)
@@ -1093,15 +1081,18 @@ func (b *Batcher) FetchUnconfirmedBatches(ctx context.Context) ([]*batch,
10931081
batch := batch{}
10941082
batch.id = bch.ID
10951083

1096-
switch bch.State {
1097-
case batchOpen:
1098-
batch.state = Open
1099-
1100-
case batchClosed:
1101-
batch.state = Closed
1102-
1103-
case batchConfirmed:
1084+
if bch.Confirmed {
11041085
batch.state = Confirmed
1086+
} else {
1087+
// We don't store Closed state separately in DB.
1088+
// If the batch is closed (included into a block, but
1089+
// not fully confirmed), it is now considered Open
1090+
// again. It will receive a spending notification as
1091+
// soon as it starts, so it is not an issue. If a sweep
1092+
// manages to be added during this time, it will be
1093+
// detected as missing when analyzing the spend
1094+
// notification and will be added to new batch.
1095+
batch.state = Open
11051096
}
11061097

11071098
batch.batchTxid = &bch.BatchTxid

0 commit comments

Comments
 (0)