Skip to content

Commit d79ec7c

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 05c208f commit d79ec7c

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.
@@ -2180,7 +2182,7 @@ func (b *batch) persist(ctx context.Context) error {
21802182
bch := &dbBatch{}
21812183

21822184
bch.ID = b.id
2183-
bch.State = stateEnumToString(b.state)
2185+
bch.Confirmed = b.state == Confirmed
21842186

21852187
if b.batchTxid != nil {
21862188
bch.BatchTxid = *b.batchTxid
@@ -2239,7 +2241,7 @@ func (b *batch) getBatchDestAddr(ctx context.Context) (btcutil.Address, error) {
22392241

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

22452247
id, err := b.store.InsertSweepBatch(ctx, bch)
@@ -2340,18 +2342,3 @@ func clampBatchFee(fee btcutil.Amount,
23402342

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

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
@@ -761,7 +749,7 @@ func (b *Batcher) AddSweep(ctx context.Context, sweepReq *SweepRequest) error {
761749
"sweep %x: %w", sweep.swapHash[:6], err)
762750
}
763751

764-
if parentBatch.State == batchConfirmed {
752+
if parentBatch.Confirmed {
765753
fullyConfirmed = true
766754
}
767755
}
@@ -845,7 +833,7 @@ func (b *Batcher) handleSweeps(ctx context.Context, sweeps []*sweep,
845833
if completed && *notifier != (SpendNotifier{}) {
846834
// The parent batch is indeed confirmed, meaning it is complete
847835
// and we won't be able to attach this sweep to it.
848-
if parentBatch.State == batchConfirmed {
836+
if parentBatch.Confirmed {
849837
return b.monitorSpendAndNotify(
850838
ctx, sweep, parentBatch.ID, notifier,
851839
)
@@ -1094,15 +1082,18 @@ func (b *Batcher) FetchUnconfirmedBatches(ctx context.Context) ([]*batch,
10941082
batch := batch{}
10951083
batch.id = bch.ID
10961084

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

11081099
batch.batchTxid = &bch.BatchTxid

0 commit comments

Comments
 (0)