Skip to content

Commit 7fb7c2b

Browse files
committed
sweepbatcher: customize transaction labels
Previously sweepbatcher used loop/labels.LoopOutBatchSweepSuccess to assign transactions labels. The value is "BatchOutSweepSuccess -- $batch_id", which does not fit use cases outside of loop-out. Now there is option WithTxLabeler which sets a function used to generate the label.
1 parent 98fa740 commit 7fb7c2b

File tree

3 files changed

+175
-4
lines changed

3 files changed

+175
-4
lines changed

sweepbatcher/sweep_batch.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/btcsuite/btcd/wire"
2020
"github.com/btcsuite/btclog"
2121
"github.com/lightninglabs/lndclient"
22-
"github.com/lightninglabs/loop/labels"
2322
"github.com/lightninglabs/loop/loopdb"
2423
"github.com/lightninglabs/loop/swap"
2524
sweeppkg "github.com/lightninglabs/loop/sweep"
@@ -152,6 +151,10 @@ type batchConfig struct {
152151
// external source of fee rates (FeeRateProvider).
153152
noBumping bool
154153

154+
// txLabeler is a function generating a transaction label. It is called
155+
// before publishing a batch transaction. Batch ID is passed to it.
156+
txLabeler func(batchID int32) string
157+
155158
// customMuSig2Signer is a custom signer. If it is set, it is used to
156159
// create musig2 signatures instead of musig2SignSweep and signerClient.
157160
// Note that musig2SignSweep must be nil in this case, however signer
@@ -904,7 +907,7 @@ func (b *batch) publishBatch(ctx context.Context) (btcutil.Amount, error) {
904907
b.debugLogTx("serialized non-coop sweep", batchTx)
905908

906909
err = b.wallet.PublishTransaction(
907-
ctx, batchTx, labels.LoopOutBatchSweepSuccess(b.id),
910+
ctx, batchTx, b.cfg.txLabeler(b.id),
908911
)
909912
if err != nil {
910913
return fee, err
@@ -1053,7 +1056,7 @@ func (b *batch) publishBatchCoop(ctx context.Context) (btcutil.Amount,
10531056
b.debugLogTx("serialized coop sweep", batchTx)
10541057

10551058
err = b.wallet.PublishTransaction(
1056-
ctx, batchTx, labels.LoopOutBatchSweepSuccess(b.id),
1059+
ctx, batchTx, b.cfg.txLabeler(b.id),
10571060
)
10581061
if err != nil {
10591062
return fee, err, true

sweepbatcher/sweep_batcher.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/btcsuite/btcd/chaincfg/chainhash"
1414
"github.com/btcsuite/btcd/wire"
1515
"github.com/lightninglabs/lndclient"
16+
"github.com/lightninglabs/loop/labels"
1617
"github.com/lightninglabs/loop/loopdb"
1718
"github.com/lightninglabs/loop/swap"
1819
"github.com/lightninglabs/loop/utils"
@@ -276,6 +277,10 @@ type Batcher struct {
276277
// ignored and fee bumping by sweepbatcher is disabled.
277278
customFeeRate FeeRateProvider
278279

280+
// txLabeler is a function generating a transaction label. It is called
281+
// before publishing a batch transaction. Batch ID is passed to it.
282+
txLabeler func(batchID int32) string
283+
279284
// customMuSig2Signer is a custom signer. If it is set, it is used to
280285
// create musig2 signatures instead of musig2SignSweep and signerClient.
281286
// Note that musig2SignSweep must be nil in this case, however signer
@@ -307,6 +312,10 @@ type BatcherConfig struct {
307312
// ignored and fee bumping by sweepbatcher is disabled.
308313
customFeeRate FeeRateProvider
309314

315+
// txLabeler is a function generating a transaction label. It is called
316+
// before publishing a batch transaction. Batch ID is passed to it.
317+
txLabeler func(batchID int32) string
318+
310319
// customMuSig2Signer is a custom signer. If it is set, it is used to
311320
// create musig2 signatures instead of musig2SignSweep and signerClient.
312321
// Note that musig2SignSweep must be nil in this case, however signer
@@ -357,6 +366,15 @@ func WithCustomFeeRate(customFeeRate FeeRateProvider) BatcherOption {
357366
}
358367
}
359368

369+
// WithTxLabeler sets a function generating a transaction label. It is called
370+
// before publishing a batch transaction. Batch ID is passed to the function.
371+
// By default, loop/labels.LoopOutBatchSweepSuccess is used.
372+
func WithTxLabeler(txLabeler func(batchID int32) string) BatcherOption {
373+
return func(cfg *BatcherConfig) {
374+
cfg.txLabeler = txLabeler
375+
}
376+
}
377+
360378
// WithCustomSignMuSig2 instructs sweepbatcher to use a custom function to
361379
// produce MuSig2 signatures. If it is set, it is used to create
362380
// musig2 signatures instead of musig2SignSweep and signerClient. Note
@@ -376,7 +394,11 @@ func NewBatcher(wallet lndclient.WalletKitClient,
376394
store BatcherStore, sweepStore SweepFetcher,
377395
opts ...BatcherOption) *Batcher {
378396

379-
var cfg BatcherConfig
397+
cfg := BatcherConfig{
398+
// By default, loop/labels.LoopOutBatchSweepSuccess is used
399+
// to label sweep transactions.
400+
txLabeler: labels.LoopOutBatchSweepSuccess,
401+
}
380402
for _, opt := range opts {
381403
opt(&cfg)
382404
}
@@ -409,6 +431,7 @@ func NewBatcher(wallet lndclient.WalletKitClient,
409431
initialDelay: cfg.initialDelay,
410432
publishDelay: cfg.publishDelay,
411433
customFeeRate: cfg.customFeeRate,
434+
txLabeler: cfg.txLabeler,
412435
customMuSig2Signer: cfg.customMuSig2Signer,
413436
}
414437
}
@@ -1024,6 +1047,7 @@ func (b *Batcher) newBatchConfig(maxTimeoutDistance int32) batchConfig {
10241047
return batchConfig{
10251048
maxTimeoutDistance: maxTimeoutDistance,
10261049
noBumping: b.customFeeRate != nil,
1050+
txLabeler: b.txLabeler,
10271051
customMuSig2Signer: b.customMuSig2Signer,
10281052
clock: b.clock,
10291053
}

sweepbatcher/sweep_batcher_test.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/btcsuite/btcd/chaincfg/chainhash"
1616
"github.com/btcsuite/btcd/wire"
1717
"github.com/btcsuite/btclog"
18+
"github.com/lightninglabs/lndclient"
1819
"github.com/lightninglabs/loop/loopdb"
1920
"github.com/lightninglabs/loop/test"
2021
"github.com/lightninglabs/loop/utils"
@@ -401,6 +402,144 @@ func testFeeBumping(t *testing.T, store testStore,
401402
}
402403
}
403404

405+
// walletKitWrapper wraps a wallet kit and memorizes the label of the most
406+
// recent published transaction.
407+
type walletKitWrapper struct {
408+
lndclient.WalletKitClient
409+
410+
lastLabel string
411+
}
412+
413+
// PublishTransaction publishes the transaction and memorizes its label.
414+
func (w *walletKitWrapper) PublishTransaction(ctx context.Context,
415+
tx *wire.MsgTx, label string) error {
416+
417+
w.lastLabel = label
418+
419+
return w.WalletKitClient.PublishTransaction(ctx, tx, label)
420+
}
421+
422+
// testTxLabeler tests transaction labels.
423+
func testTxLabeler(t *testing.T, store testStore,
424+
batcherStore testBatcherStore) {
425+
426+
defer test.Guard(t)()
427+
428+
lnd := test.NewMockLnd()
429+
ctx, cancel := context.WithCancel(context.Background())
430+
431+
sweepStore, err := NewSweepFetcherFromSwapStore(store, lnd.ChainParams)
432+
require.NoError(t, err)
433+
434+
walletKit := &walletKitWrapper{WalletKitClient: lnd.WalletKit}
435+
436+
batcher := NewBatcher(walletKit, lnd.ChainNotifier, lnd.Signer,
437+
testMuSig2SignSweep, testVerifySchnorrSig, lnd.ChainParams,
438+
batcherStore, sweepStore)
439+
440+
var (
441+
runErr error
442+
wg sync.WaitGroup
443+
)
444+
445+
wg.Add(1)
446+
go func() {
447+
defer wg.Done()
448+
runErr = batcher.Run(ctx)
449+
}()
450+
451+
// Create a sweep request.
452+
sweepReq1 := SweepRequest{
453+
SwapHash: lntypes.Hash{1, 1, 1},
454+
Value: 111,
455+
Outpoint: wire.OutPoint{
456+
Hash: chainhash.Hash{1, 1},
457+
Index: 1,
458+
},
459+
Notifier: &dummyNotifier,
460+
}
461+
462+
swap1 := &loopdb.LoopOutContract{
463+
SwapContract: loopdb.SwapContract{
464+
CltvExpiry: 111,
465+
AmountRequested: 111,
466+
ProtocolVersion: loopdb.ProtocolVersionMuSig2,
467+
HtlcKeys: htlcKeys,
468+
},
469+
470+
DestAddr: destAddr,
471+
SwapInvoice: swapInvoice,
472+
SweepConfTarget: 111,
473+
}
474+
475+
err = store.CreateLoopOut(ctx, sweepReq1.SwapHash, swap1)
476+
require.NoError(t, err)
477+
store.AssertLoopOutStored()
478+
479+
// Deliver sweep request to batcher.
480+
require.NoError(t, batcher.AddSweep(&sweepReq1))
481+
482+
// Eventually request will be consumed and a new batch will spin up.
483+
require.Eventually(t, func() bool {
484+
return len(batcher.batches) == 1
485+
}, test.Timeout, eventuallyCheckFrequency)
486+
487+
// When batch is successfully created it will execute it's first step,
488+
// which leads to a spend monitor of the primary sweep.
489+
<-lnd.RegisterSpendChannel
490+
491+
// Wait for tx to be published.
492+
<-lnd.TxPublishChannel
493+
494+
// Find the batch and assign it to a local variable for easier access.
495+
var theBatch *batch
496+
for _, btch := range batcher.batches {
497+
if btch.primarySweepID == sweepReq1.SwapHash {
498+
theBatch = btch
499+
}
500+
}
501+
502+
// Now test the label.
503+
wantLabel := fmt.Sprintf("BatchOutSweepSuccess -- %d", theBatch.id)
504+
require.Equal(t, wantLabel, walletKit.lastLabel)
505+
506+
// Now make the batcher quit by canceling the context.
507+
cancel()
508+
wg.Wait()
509+
checkBatcherError(t, runErr)
510+
511+
// Define dummy tx labeler, always returning "test".
512+
txLabeler := func(batchID int32) string {
513+
return "test"
514+
}
515+
516+
// Now try it with option WithTxLabeler.
517+
batcher = NewBatcher(walletKit, lnd.ChainNotifier, lnd.Signer,
518+
testMuSig2SignSweep, testVerifySchnorrSig, lnd.ChainParams,
519+
batcherStore, sweepStore, WithTxLabeler(txLabeler))
520+
521+
ctx, cancel = context.WithCancel(context.Background())
522+
wg.Add(1)
523+
go func() {
524+
defer wg.Done()
525+
runErr = batcher.Run(ctx)
526+
}()
527+
528+
// Expect batch to register for spending.
529+
<-lnd.RegisterSpendChannel
530+
531+
// Wait for tx to be published.
532+
<-lnd.TxPublishChannel
533+
534+
// Now test the label.
535+
require.Equal(t, "test", walletKit.lastLabel)
536+
537+
// Now make the batcher quit by canceling the context.
538+
cancel()
539+
wg.Wait()
540+
checkBatcherError(t, runErr)
541+
}
542+
404543
// testSweepBatcherSimpleLifecycle tests the simple lifecycle of the batches
405544
// that are created and run by the batcher.
406545
func testSweepBatcherSimpleLifecycle(t *testing.T, store testStore,
@@ -2767,6 +2906,11 @@ func TestFeeBumping(t *testing.T) {
27672906
})
27682907
}
27692908

2909+
// TestTxLabeler tests transaction labels.
2910+
func TestTxLabeler(t *testing.T) {
2911+
runTests(t, testTxLabeler)
2912+
}
2913+
27702914
// TestSweepBatcherSimpleLifecycle tests the simple lifecycle of the batches
27712915
// that are created and run by the batcher.
27722916
func TestSweepBatcherSimpleLifecycle(t *testing.T) {

0 commit comments

Comments
 (0)