9
9
"math"
10
10
"strings"
11
11
"sync"
12
+ "sync/atomic"
12
13
"time"
13
14
14
15
"github.com/btcsuite/btcd/blockchain"
@@ -284,8 +285,8 @@ type batch struct {
284
285
// cfg is the configuration for this batch.
285
286
cfg * batchConfig
286
287
287
- // log is the logger for this batch.
288
- log btclog.Logger
288
+ // log_ is the logger for this batch.
289
+ log_ atomic. Pointer [ btclog.Logger ]
289
290
290
291
wg sync.WaitGroup
291
292
}
@@ -387,7 +388,7 @@ func NewBatchFromDB(cfg batchConfig, bk batchKit) (*batch, error) {
387
388
}
388
389
}
389
390
390
- return & batch {
391
+ b := & batch {
391
392
id : bk .id ,
392
393
state : bk .state ,
393
394
primarySweepID : bk .primaryID ,
@@ -412,9 +413,42 @@ func NewBatchFromDB(cfg batchConfig, bk batchKit) (*batch, error) {
412
413
publishErrorHandler : bk .publishErrorHandler ,
413
414
purger : bk .purger ,
414
415
store : bk .store ,
415
- log : bk .log ,
416
416
cfg : & cfg ,
417
- }, nil
417
+ }
418
+
419
+ b .setLog (bk .log )
420
+
421
+ return b , nil
422
+ }
423
+
424
+ // log returns current logger.
425
+ func (b * batch ) log () btclog.Logger {
426
+ return * b .log_ .Load ()
427
+ }
428
+
429
+ // setLog atomically replaces the logger.
430
+ func (b * batch ) setLog (logger btclog.Logger ) {
431
+ b .log_ .Store (& logger )
432
+ }
433
+
434
+ // Debugf logs a message with level DEBUG.
435
+ func (b * batch ) Debugf (format string , params ... interface {}) {
436
+ b .log ().Debugf (format , params ... )
437
+ }
438
+
439
+ // Infof logs a message with level INFO.
440
+ func (b * batch ) Infof (format string , params ... interface {}) {
441
+ b .log ().Infof (format , params ... )
442
+ }
443
+
444
+ // Warnf logs a message with level WARN.
445
+ func (b * batch ) Warnf (format string , params ... interface {}) {
446
+ b .log ().Warnf (format , params ... )
447
+ }
448
+
449
+ // Errorf logs a message with level ERROR.
450
+ func (b * batch ) Errorf (format string , params ... interface {}) {
451
+ b .log ().Errorf (format , params ... )
418
452
}
419
453
420
454
// addSweep tries to add a sweep to the batch. If this is the first sweep being
@@ -430,7 +464,7 @@ func (b *batch) addSweep(ctx context.Context, sweep *sweep) (bool, error) {
430
464
// If the provided sweep is nil, we can't proceed with any checks, so
431
465
// we just return early.
432
466
if sweep == nil {
433
- b .log . Infof ("the sweep is nil" )
467
+ b .Infof ("the sweep is nil" )
434
468
435
469
return false , nil
436
470
}
@@ -473,7 +507,7 @@ func (b *batch) addSweep(ctx context.Context, sweep *sweep) (bool, error) {
473
507
// the batch, do not add another sweep to prevent the tx from becoming
474
508
// non-standard.
475
509
if len (b .sweeps ) >= MaxSweepsPerBatch {
476
- b .log . Infof ("the batch has already too many sweeps ( %d >= %d) " ,
510
+ b .Infof ("the batch has already too many sweeps %d >= %d" ,
477
511
len (b .sweeps ), MaxSweepsPerBatch )
478
512
479
513
return false , nil
@@ -483,7 +517,7 @@ func (b *batch) addSweep(ctx context.Context, sweep *sweep) (bool, error) {
483
517
// arrive here after the batch got closed because of a spend. In this
484
518
// case we cannot add the sweep to this batch.
485
519
if b .state != Open {
486
- b .log . Infof ("the batch state (%v) is not open" , b .state )
520
+ b .Infof ("the batch state (%v) is not open" , b .state )
487
521
488
522
return false , nil
489
523
}
@@ -493,15 +527,15 @@ func (b *batch) addSweep(ctx context.Context, sweep *sweep) (bool, error) {
493
527
// we cannot add this sweep to the batch.
494
528
for _ , s := range b .sweeps {
495
529
if s .isExternalAddr {
496
- b .log . Infof ("the batch already has a sweep (%x) with " +
530
+ b .Infof ("the batch already has a sweep %x with " +
497
531
"an external address" , s .swapHash [:6 ])
498
532
499
533
return false , nil
500
534
}
501
535
502
536
if sweep .isExternalAddr {
503
- b .log . Infof ("the batch is not empty and new sweep (%x) " +
504
- " has an external address" , sweep .swapHash [:6 ])
537
+ b .Infof ("the batch is not empty and new sweep %x " +
538
+ "has an external address" , sweep .swapHash [:6 ])
505
539
506
540
return false , nil
507
541
}
@@ -515,7 +549,7 @@ func (b *batch) addSweep(ctx context.Context, sweep *sweep) (bool, error) {
515
549
int32 (math .Abs (float64 (sweep .timeout - s .timeout )))
516
550
517
551
if timeoutDistance > b .cfg .maxTimeoutDistance {
518
- b .log . Infof ("too long timeout distance between the " +
552
+ b .Infof ("too long timeout distance between the " +
519
553
"batch and sweep %x: %d > %d" ,
520
554
sweep .swapHash [:6 ], timeoutDistance ,
521
555
b .cfg .maxTimeoutDistance )
@@ -544,7 +578,7 @@ func (b *batch) addSweep(ctx context.Context, sweep *sweep) (bool, error) {
544
578
}
545
579
546
580
// Add the sweep to the batch's sweeps.
547
- b .log . Infof ("adding sweep %x" , sweep .swapHash [:6 ])
581
+ b .Infof ("adding sweep %x" , sweep .swapHash [:6 ])
548
582
b .sweeps [sweep .swapHash ] = * sweep
549
583
550
584
// Update FeeRate. Max(sweep.minFeeRate) for all the sweeps of
@@ -572,7 +606,7 @@ func (b *batch) sweepExists(hash lntypes.Hash) bool {
572
606
573
607
// Wait waits for the batch to gracefully stop.
574
608
func (b * batch ) Wait () {
575
- b .log . Infof ("Stopping" )
609
+ b .Infof ("Stopping" )
576
610
<- b .finished
577
611
}
578
612
@@ -613,8 +647,7 @@ func (b *batch) Run(ctx context.Context) error {
613
647
// Set currentHeight here, because it may be needed in monitorSpend.
614
648
select {
615
649
case b .currentHeight = <- blockChan :
616
- b .log .Debugf ("initial height for the batch is %v" ,
617
- b .currentHeight )
650
+ b .Debugf ("initial height for the batch is %v" , b .currentHeight )
618
651
619
652
case <- runCtx .Done ():
620
653
return runCtx .Err ()
@@ -652,7 +685,7 @@ func (b *batch) Run(ctx context.Context) error {
652
685
// completes.
653
686
timerChan := clock .TickAfter (b .cfg .batchPublishDelay )
654
687
655
- b .log . Infof ("started, primary %x, total sweeps %v" ,
688
+ b .Infof ("started, primary %x, total sweeps %v" ,
656
689
b .primarySweepID [0 :6 ], len (b .sweeps ))
657
690
658
691
for {
@@ -662,15 +695,15 @@ func (b *batch) Run(ctx context.Context) error {
662
695
663
696
// blockChan provides immediately the current tip.
664
697
case height := <- blockChan :
665
- b .log . Debugf ("received block %v" , height )
698
+ b .Debugf ("received block %v" , height )
666
699
667
700
// Set the timer to publish the batch transaction after
668
701
// the configured delay.
669
702
timerChan = clock .TickAfter (b .cfg .batchPublishDelay )
670
703
b .currentHeight = height
671
704
672
705
case <- initialDelayChan :
673
- b .log . Debugf ("initial delay of duration %v has ended" ,
706
+ b .Debugf ("initial delay of duration %v has ended" ,
674
707
b .cfg .initialDelay )
675
708
676
709
// Set the timer to publish the batch transaction after
@@ -680,8 +713,8 @@ func (b *batch) Run(ctx context.Context) error {
680
713
case <- timerChan :
681
714
// Check that batch is still open.
682
715
if b .state != Open {
683
- b .log . Debugf ("Skipping publishing, because the " +
684
- " batch is not open (%v)." , b .state )
716
+ b .Debugf ("Skipping publishing, because " +
717
+ "the batch is not open (%v)." , b .state )
685
718
continue
686
719
}
687
720
@@ -695,7 +728,7 @@ func (b *batch) Run(ctx context.Context) error {
695
728
// initialDelayChan has just fired, this check passes.
696
729
now := clock .Now ()
697
730
if skipBefore .After (now ) {
698
- b .log . Debugf (stillWaitingMsg , skipBefore , now )
731
+ b .Debugf (stillWaitingMsg , skipBefore , now )
699
732
continue
700
733
}
701
734
@@ -715,8 +748,8 @@ func (b *batch) Run(ctx context.Context) error {
715
748
716
749
case <- b .reorgChan :
717
750
b .state = Open
718
- b .log . Warnf ("reorg detected, batch is able to accept " +
719
- "new sweeps" )
751
+ b .Warnf ("reorg detected, batch is able to " +
752
+ "accept new sweeps" )
720
753
721
754
err := b .monitorSpend (ctx , b .sweeps [b .primarySweepID ])
722
755
if err != nil {
@@ -755,8 +788,10 @@ func (b *batch) timeout() int32 {
755
788
func (b * batch ) isUrgent (skipBefore time.Time ) bool {
756
789
timeout := b .timeout ()
757
790
if timeout <= 0 {
758
- b .log .Warnf ("Method timeout() returned %v. Number of" +
759
- " sweeps: %d. It may be an empty batch." ,
791
+ // This may happen if the batch is empty or if SweepInfo.Timeout
792
+ // is not set, may be possible in tests or if there is a bug.
793
+ b .Warnf ("Method timeout() returned %v. Number of " +
794
+ "sweeps: %d. It may be an empty batch." ,
760
795
timeout , len (b .sweeps ))
761
796
return false
762
797
}
@@ -779,7 +814,7 @@ func (b *batch) isUrgent(skipBefore time.Time) bool {
779
814
return false
780
815
}
781
816
782
- b .log . Debugf ("cancelling waiting for urgent sweep (timeBank is %v, " +
817
+ b .Debugf ("cancelling waiting for urgent sweep (timeBank is %v, " +
783
818
"remainingWaiting is %v)" , timeBank , remainingWaiting )
784
819
785
820
// Signal to the caller to cancel initialDelay.
@@ -795,7 +830,7 @@ func (b *batch) publish(ctx context.Context) error {
795
830
)
796
831
797
832
if len (b .sweeps ) == 0 {
798
- b .log . Debugf ("skipping publish: no sweeps in the batch" )
833
+ b .Debugf ("skipping publish: no sweeps in the batch" )
799
834
800
835
return nil
801
836
}
@@ -808,7 +843,7 @@ func (b *batch) publish(ctx context.Context) error {
808
843
809
844
// logPublishError is a function which logs publish errors.
810
845
logPublishError := func (errMsg string , err error ) {
811
- b .publishErrorHandler (err , errMsg , b .log )
846
+ b .publishErrorHandler (err , errMsg , b .log () )
812
847
}
813
848
814
849
fee , err , signSuccess = b .publishMixedBatch (ctx )
@@ -830,9 +865,9 @@ func (b *batch) publish(ctx context.Context) error {
830
865
}
831
866
}
832
867
833
- b .log . Infof ("published, total sweeps: %v, fees: %v" , len (b .sweeps ), fee )
868
+ b .Infof ("published, total sweeps: %v, fees: %v" , len (b .sweeps ), fee )
834
869
for _ , sweep := range b .sweeps {
835
- b .log . Infof ("published sweep %x, value: %v" ,
870
+ b .Infof ("published sweep %x, value: %v" ,
836
871
sweep .swapHash [:6 ], sweep .value )
837
872
}
838
873
@@ -1026,7 +1061,7 @@ func (b *batch) publishMixedBatch(ctx context.Context) (btcutil.Amount, error,
1026
1061
coopInputs int
1027
1062
)
1028
1063
for attempt := 1 ; ; attempt ++ {
1029
- b .log . Infof ("Attempt %d of collecting cooperative signatures." ,
1064
+ b .Infof ("Attempt %d of collecting cooperative signatures." ,
1030
1065
attempt )
1031
1066
1032
1067
// Construct unsigned batch transaction.
@@ -1062,7 +1097,7 @@ func (b *batch) publishMixedBatch(ctx context.Context) (btcutil.Amount, error,
1062
1097
ctx , i , sweep , tx , prevOutsMap , psbtBytes ,
1063
1098
)
1064
1099
if err != nil {
1065
- b .log . Infof ("cooperative signing failed for " +
1100
+ b .Infof ("cooperative signing failed for " +
1066
1101
"sweep %x: %v" , sweep .swapHash [:6 ], err )
1067
1102
1068
1103
// Set coopFailed flag for this sweep in all the
@@ -1201,7 +1236,7 @@ func (b *batch) publishMixedBatch(ctx context.Context) (btcutil.Amount, error,
1201
1236
}
1202
1237
}
1203
1238
txHash := tx .TxHash ()
1204
- b .log . Infof ("attempting to publish batch tx=%v with feerate=%v, " +
1239
+ b .Infof ("attempting to publish batch tx=%v with feerate=%v, " +
1205
1240
"weight=%v, feeForWeight=%v, fee=%v, sweeps=%d, " +
1206
1241
"%d cooperative: (%s) and %d non-cooperative (%s), destAddr=%s" ,
1207
1242
txHash , b .rbfCache .FeeRate , weight , feeForWeight , fee ,
@@ -1215,7 +1250,7 @@ func (b *batch) publishMixedBatch(ctx context.Context) (btcutil.Amount, error,
1215
1250
blockchain .GetTransactionWeight (btcutil .NewTx (tx )),
1216
1251
)
1217
1252
if realWeight != weight {
1218
- b .log . Warnf ("actual weight of tx %v is %v, estimated as %d" ,
1253
+ b .Warnf ("actual weight of tx %v is %v, estimated as %d" ,
1219
1254
txHash , realWeight , weight )
1220
1255
}
1221
1256
@@ -1239,11 +1274,11 @@ func (b *batch) debugLogTx(msg string, tx *wire.MsgTx) {
1239
1274
// Serialize the transaction and convert to hex string.
1240
1275
buf := bytes .NewBuffer (make ([]byte , 0 , tx .SerializeSize ()))
1241
1276
if err := tx .Serialize (buf ); err != nil {
1242
- b .log . Errorf ("failed to serialize tx for debug log: %v" , err )
1277
+ b .Errorf ("failed to serialize tx for debug log: %v" , err )
1243
1278
return
1244
1279
}
1245
1280
1246
- b .log . Debugf ("%s: %s" , msg , hex .EncodeToString (buf .Bytes ()))
1281
+ b .Debugf ("%s: %s" , msg , hex .EncodeToString (buf .Bytes ()))
1247
1282
}
1248
1283
1249
1284
// musig2sign signs one sweep using musig2.
@@ -1405,15 +1440,16 @@ func (b *batch) updateRbfRate(ctx context.Context) error {
1405
1440
if b .rbfCache .FeeRate == 0 {
1406
1441
// We set minFeeRate in each sweep, so fee rate is expected to
1407
1442
// be initiated here.
1408
- b .log . Warnf ("rbfCache.FeeRate is 0, which must not happen." )
1443
+ b .Warnf ("rbfCache.FeeRate is 0, which must not happen." )
1409
1444
1410
1445
if b .cfg .batchConfTarget == 0 {
1411
- b .log . Warnf ("updateRbfRate called with zero " +
1446
+ b .Warnf ("updateRbfRate called with zero " +
1412
1447
"batchConfTarget" )
1413
1448
}
1414
1449
1415
- b .log . Infof ("initializing rbf fee rate for conf target=%v" ,
1450
+ b .Infof ("initializing rbf fee rate for conf target=%v" ,
1416
1451
b .cfg .batchConfTarget )
1452
+
1417
1453
rate , err := b .wallet .EstimateFeeRate (
1418
1454
ctx , b .cfg .batchConfTarget ,
1419
1455
)
@@ -1453,6 +1489,7 @@ func (b *batch) monitorSpend(ctx context.Context, primarySweep sweep) error {
1453
1489
)
1454
1490
if err != nil {
1455
1491
cancel ()
1492
+
1456
1493
return err
1457
1494
}
1458
1495
@@ -1461,7 +1498,7 @@ func (b *batch) monitorSpend(ctx context.Context, primarySweep sweep) error {
1461
1498
defer cancel ()
1462
1499
defer b .wg .Done ()
1463
1500
1464
- b .log . Infof ("monitoring spend for outpoint %s" ,
1501
+ b .Infof ("monitoring spend for outpoint %s" ,
1465
1502
primarySweep .outpoint .String ())
1466
1503
1467
1504
for {
@@ -1584,7 +1621,7 @@ func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error {
1584
1621
if len (spendTx .TxOut ) > 0 {
1585
1622
b .batchPkScript = spendTx .TxOut [0 ].PkScript
1586
1623
} else {
1587
- b .log . Warnf ("transaction %v has no outputs" , txHash )
1624
+ b .Warnf ("transaction %v has no outputs" , txHash )
1588
1625
}
1589
1626
1590
1627
// As a previous version of the batch transaction may get confirmed,
@@ -1666,13 +1703,13 @@ func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error {
1666
1703
1667
1704
err := b .purger (& sweep )
1668
1705
if err != nil {
1669
- b .log . Errorf ("unable to purge sweep %x: %v" ,
1706
+ b .Errorf ("unable to purge sweep %x: %v" ,
1670
1707
sweep .SwapHash [:6 ], err )
1671
1708
}
1672
1709
}
1673
1710
}()
1674
1711
1675
- b .log . Infof ("spent, total sweeps: %v, purged sweeps: %v" ,
1712
+ b .Infof ("spent, total sweeps: %v, purged sweeps: %v" ,
1676
1713
len (notifyList ), len (purgeList ))
1677
1714
1678
1715
err := b .monitorConfirmations (ctx )
@@ -1690,7 +1727,7 @@ func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error {
1690
1727
// handleConf handles a confirmation notification. This is the final step of the
1691
1728
// batch. Here we signal to the batcher that this batch was completed.
1692
1729
func (b * batch ) handleConf (ctx context.Context ) error {
1693
- b .log . Infof ("confirmed in txid %s" , b .batchTxid )
1730
+ b .Infof ("confirmed in txid %s" , b .batchTxid )
1694
1731
b .state = Confirmed
1695
1732
1696
1733
return b .store .ConfirmBatch (ctx , b .id )
@@ -1769,7 +1806,7 @@ func (b *batch) insertAndAcquireID(ctx context.Context) (int32, error) {
1769
1806
}
1770
1807
1771
1808
b .id = id
1772
- b .log = batchPrefixLogger (fmt .Sprintf ("%d" , b .id ))
1809
+ b .setLog ( batchPrefixLogger (fmt .Sprintf ("%d" , b .id ) ))
1773
1810
1774
1811
return id , nil
1775
1812
}
0 commit comments