@@ -162,6 +162,22 @@ type VerifySchnorrSig func(pubKey *btcec.PublicKey, hash, sig []byte) error
162162type FeeRateProvider func (ctx context.Context ,
163163 swapHash lntypes.Hash ) (chainfee.SatPerKWeight , error )
164164
165+ // InitialDelayProvider returns the duration after new batch creation before it
166+ // is first published. It allows to customize the duration based on swap hash,
167+ // sweep outpoint, sweep size and expity block height. There is a trade-off
168+ // between better grouping and getting funds better. If the function returns an
169+ // error, no delay is used and the error is logged as a warning.
170+ type InitialDelayProvider func (ctx context.Context , swapHash lntypes.Hash ,
171+ outpoint wire.OutPoint , value btcutil.Amount ,
172+ timeout int32 ) (time.Duration , error )
173+
174+ // zeroInitialDelay returns no delay for any sweeps.
175+ func zeroInitialDelay (_ context.Context , _ lntypes.Hash , _ wire.OutPoint ,
176+ _ btcutil.Amount , _ int32 ) (time.Duration , error ) {
177+
178+ return 0 , nil
179+ }
180+
165181// PublishErrorHandler is a function that handles transaction publishing error.
166182type PublishErrorHandler func (err error , errMsg string , log btclog.Logger )
167183
@@ -296,13 +312,13 @@ type Batcher struct {
296312 // clock provides methods to work with time and timers.
297313 clock clock.Clock
298314
299- // initialDelay is the delay of first batch publishing after creation.
300- // It only affects newly created batches, not batches loaded from DB,
301- // so publishing does happen in case of a daemon restart (especially
302- // important in case of a crashloop). If a sweep is about to expire
303- // (time until timeout is less that 2x initialDelay), then waiting is
304- // skipped.
305- initialDelay time. Duration
315+ // initialDelayProvider provides the delay of first batch publishing
316+ // after creation. It only affects newly created batches, not batches
317+ // loaded from DB, so publishing does happen in case of a daemon restart
318+ // (especially important in case of a crashloop). If a sweep is about to
319+ // expire (time until timeout is less that 2x initialDelay), then
320+ // waiting is skipped.
321+ initialDelayProvider InitialDelayProvider
306322
307323 // publishDelay is the delay of batch publishing that is applied in the
308324 // beginning, after the appearance of a new block in the network or
@@ -336,13 +352,13 @@ type BatcherConfig struct {
336352 // clock provides methods to work with time and timers.
337353 clock clock.Clock
338354
339- // initialDelay is the delay of first batch publishing after creation.
340- // It only affects newly created batches, not batches loaded from DB,
341- // so publishing does happen in case of a daemon restart (especially
342- // important in case of a crashloop). If a sweep is about to expire
343- // (time until timeout is less that 2x initialDelay), then waiting is
344- // skipped.
345- initialDelay time. Duration
355+ // initialDelayProvider provides the delay of first batch publishing
356+ // after creation. It only affects newly created batches, not batches
357+ // loaded from DB, so publishing does happen in case of a daemon restart
358+ // (especially important in case of a crashloop). If a sweep is about to
359+ // expire (time until timeout is less that 2x initialDelay), then
360+ // waiting is skipped.
361+ initialDelayProvider InitialDelayProvider
346362
347363 // publishDelay is the delay of batch publishing that is applied in the
348364 // beginning, after the appearance of a new block in the network or
@@ -387,9 +403,9 @@ func WithClock(clock clock.Clock) BatcherOption {
387403// better grouping. Defaults to 0s (no initial delay). If a sweep is about
388404// to expire (time until timeout is less that 2x initialDelay), then waiting
389405// is skipped.
390- func WithInitialDelay (initialDelay time. Duration ) BatcherOption {
406+ func WithInitialDelay (provider InitialDelayProvider ) BatcherOption {
391407 return func (cfg * BatcherConfig ) {
392- cfg .initialDelay = initialDelay
408+ cfg .initialDelayProvider = provider
393409 }
394410}
395411
@@ -475,27 +491,27 @@ func NewBatcher(wallet lndclient.WalletKitClient,
475491 }
476492
477493 return & Batcher {
478- batches : make (map [int32 ]* batch ),
479- sweepReqs : make (chan SweepRequest ),
480- testReqs : make (chan * testRequest ),
481- errChan : make (chan error , 1 ),
482- quit : make (chan struct {}),
483- initDone : make (chan struct {}),
484- wallet : wallet ,
485- chainNotifier : chainNotifier ,
486- signerClient : signerClient ,
487- musig2ServerSign : musig2ServerSigner ,
488- VerifySchnorrSig : verifySchnorrSig ,
489- chainParams : chainparams ,
490- store : store ,
491- sweepStore : sweepStore ,
492- clock : cfg .clock ,
493- initialDelay : cfg .initialDelay ,
494- publishDelay : cfg .publishDelay ,
495- customFeeRate : cfg .customFeeRate ,
496- txLabeler : cfg .txLabeler ,
497- customMuSig2Signer : cfg .customMuSig2Signer ,
498- publishErrorHandler : cfg .publishErrorHandler ,
494+ batches : make (map [int32 ]* batch ),
495+ sweepReqs : make (chan SweepRequest ),
496+ testReqs : make (chan * testRequest ),
497+ errChan : make (chan error , 1 ),
498+ quit : make (chan struct {}),
499+ initDone : make (chan struct {}),
500+ wallet : wallet ,
501+ chainNotifier : chainNotifier ,
502+ signerClient : signerClient ,
503+ musig2ServerSign : musig2ServerSigner ,
504+ VerifySchnorrSig : verifySchnorrSig ,
505+ chainParams : chainparams ,
506+ store : store ,
507+ sweepStore : sweepStore ,
508+ clock : cfg .clock ,
509+ initialDelayProvider : cfg .initialDelayProvider ,
510+ publishDelay : cfg .publishDelay ,
511+ customFeeRate : cfg .customFeeRate ,
512+ txLabeler : cfg .txLabeler ,
513+ customMuSig2Signer : cfg .customMuSig2Signer ,
514+ publishErrorHandler : cfg .publishErrorHandler ,
499515 }
500516}
501517
@@ -746,11 +762,10 @@ func (b *Batcher) spinUpBatch(ctx context.Context) (*batch, error) {
746762 cfg .batchPublishDelay = b .publishDelay
747763 }
748764
749- if b . initialDelay < 0 {
750- return nil , fmt . Errorf ( "negative initialDelay: %v" ,
751- b . initialDelay )
765+ cfg . initialDelayProvider = b . initialDelayProvider
766+ if cfg . initialDelayProvider == nil {
767+ cfg . initialDelayProvider = zeroInitialDelay
752768 }
753- cfg .initialDelay = b .initialDelay
754769
755770 batchKit := b .newBatchKit ()
756771
@@ -844,6 +859,8 @@ func (b *Batcher) spinUpBatchFromDB(ctx context.Context, batch *batch) error {
844859 // Note that initialDelay and batchPublishDelay are 0 for batches
845860 // recovered from DB so publishing happen in case of a daemon restart
846861 // (especially important in case of a crashloop).
862+ cfg .initialDelayProvider = zeroInitialDelay
863+
847864 newBatch , err := NewBatchFromDB (cfg , batchKit )
848865 if err != nil {
849866 return fmt .Errorf ("failed in NewBatchFromDB: %w" , err )
0 commit comments