Skip to content

Commit e814157

Browse files
committed
sweepbatcher: MinFeeRate -> WithCustomFeeRate
The reason is because we want to know in advance if fee rates come from an external source or are determined by sweepbatcher internally. Also remove WithNoBumping option. It is now a part of WithCustomFeeRate: if WithCustomFeeRate is passed, automatic fee bumping by sweepbatcher is disabled.
1 parent ccd1b31 commit e814157

File tree

3 files changed

+58
-34
lines changed

3 files changed

+58
-34
lines changed

sweepbatcher/sweep_batch.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@ type batchConfig struct {
133133
batchPublishDelay time.Duration
134134

135135
// noBumping instructs sweepbatcher not to fee bump itself and rely on
136-
// external source of fee rates (MinFeeRate). To change the fee rate,
137-
// the caller has to update it in the source of SweepInfo (interface
138-
// SweepFetcher) and re-add the sweep by calling AddSweep.
136+
// external source of fee rates (FeeRateProvider).
139137
noBumping bool
140138

141139
// customMuSig2Signer is a custom signer. If it is set, it is used to

sweepbatcher/sweep_batcher.go

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ type SweepInfo struct {
121121

122122
// DestAddr is the destination address of the sweep.
123123
DestAddr btcutil.Address
124-
125-
// MinFeeRate is minimum fee rate that must be used by a batch of
126-
// the sweep. If it is specified, confTarget is ignored.
127-
MinFeeRate chainfee.SatPerKWeight
128124
}
129125

130126
// SweepFetcher is used to get details of a sweep.
@@ -151,6 +147,11 @@ type SignMuSig2 func(ctx context.Context, muSig2Version input.MuSig2Version,
151147
// signature.
152148
type VerifySchnorrSig func(pubKey *btcec.PublicKey, hash, sig []byte) error
153149

150+
// FeeRateProvider is a function that returns min fee rate of a batch sweeping
151+
// the UTXO of the swap.
152+
type FeeRateProvider func(ctx context.Context,
153+
swapHash lntypes.Hash) (chainfee.SatPerKWeight, error)
154+
154155
// SweepRequest is a request to sweep a specific outpoint.
155156
type SweepRequest struct {
156157
// SwapHash is the hash of the swap that is being swept.
@@ -247,11 +248,10 @@ type Batcher struct {
247248
// exit.
248249
wg sync.WaitGroup
249250

250-
// noBumping instructs sweepbatcher not to fee bump itself and rely on
251-
// external source of fee rates (MinFeeRate). To change the fee rate,
252-
// the caller has to update it in the source of SweepInfo (interface
253-
// SweepFetcher) and re-add the sweep by calling AddSweep.
254-
noBumping bool
251+
// customFeeRate provides custom min fee rate per swap. The batch uses
252+
// max of the fee rates of its swaps. In this mode confTarget is
253+
// ignored and fee bumping by sweepbatcher is disabled.
254+
customFeeRate FeeRateProvider
255255

256256
// customMuSig2Signer is a custom signer. If it is set, it is used to
257257
// create musig2 signatures instead of musig2SignSweep and signerClient.
@@ -262,11 +262,10 @@ type Batcher struct {
262262

263263
// BatcherConfig holds batcher configuration.
264264
type BatcherConfig struct {
265-
// noBumping instructs sweepbatcher not to fee bump itself and rely on
266-
// external source of fee rates (MinFeeRate). To change the fee rate,
267-
// the caller has to update it in the source of SweepInfo (interface
268-
// SweepFetcher) and re-add the sweep by calling AddSweep.
269-
noBumping bool
265+
// customFeeRate provides custom min fee rate per swap. The batch uses
266+
// max of the fee rates of its swaps. In this mode confTarget is
267+
// ignored and fee bumping by sweepbatcher is disabled.
268+
customFeeRate FeeRateProvider
270269

271270
// customMuSig2Signer is a custom signer. If it is set, it is used to
272271
// create musig2 signatures instead of musig2SignSweep and signerClient.
@@ -278,13 +277,12 @@ type BatcherConfig struct {
278277
// BatcherOption configures batcher behaviour.
279278
type BatcherOption func(*BatcherConfig)
280279

281-
// WithNoBumping instructs sweepbatcher not to fee bump itself and
282-
// rely on external source of fee rates (MinFeeRate). To change the
283-
// fee rate, the caller has to update it in the source of SweepInfo
284-
// (interface SweepFetcher) and re-add the sweep by calling AddSweep.
285-
func WithNoBumping() BatcherOption {
280+
// WithCustomFeeRate instructs sweepbatcher not to fee bump itself and rely on
281+
// external source of fee rates (FeeRateProvider). To apply a fee rate change,
282+
// the caller should re-add the sweep by calling AddSweep.
283+
func WithCustomFeeRate(customFeeRate FeeRateProvider) BatcherOption {
286284
return func(cfg *BatcherConfig) {
287-
cfg.noBumping = true
285+
cfg.customFeeRate = customFeeRate
288286
}
289287
}
290288

@@ -331,7 +329,7 @@ func NewBatcher(wallet lndclient.WalletKitClient,
331329
chainParams: chainparams,
332330
store: store,
333331
sweepStore: sweepStore,
334-
noBumping: cfg.noBumping,
332+
customFeeRate: cfg.customFeeRate,
335333
customMuSig2Signer: cfg.customMuSig2Signer,
336334
}
337335
}
@@ -859,6 +857,22 @@ func (b *Batcher) loadSweep(ctx context.Context, swapHash lntypes.Hash,
859857
swapHash[:6], err)
860858
}
861859

860+
// minFeeRate is 0 by default. If customFeeRate is not provided, then
861+
// rbfCache.FeeRate is also 0 and method batch.updateRbfRate() updates
862+
// it to current fee rate according to batchConfTarget.
863+
var minFeeRate chainfee.SatPerKWeight
864+
if b.customFeeRate != nil {
865+
minFeeRate, err = b.customFeeRate(ctx, swapHash)
866+
if err != nil {
867+
return nil, fmt.Errorf("failed to fetch min fee rate "+
868+
"for %x: %w", swapHash[:6], err)
869+
}
870+
if minFeeRate < chainfee.AbsoluteFeePerKwFloor {
871+
return nil, fmt.Errorf("min fee rate too low (%v) for "+
872+
"%x", minFeeRate, swapHash[:6])
873+
}
874+
}
875+
862876
return &sweep{
863877
swapHash: swapHash,
864878
outpoint: outpoint,
@@ -874,15 +888,15 @@ func (b *Batcher) loadSweep(ctx context.Context, swapHash lntypes.Hash,
874888
protocolVersion: s.ProtocolVersion,
875889
isExternalAddr: s.IsExternalAddr,
876890
destAddr: s.DestAddr,
877-
minFeeRate: s.MinFeeRate,
891+
minFeeRate: minFeeRate,
878892
}, nil
879893
}
880894

881895
// newBatchConfig creates new batch config.
882896
func (b *Batcher) newBatchConfig(maxTimeoutDistance int32) batchConfig {
883897
return batchConfig{
884898
maxTimeoutDistance: maxTimeoutDistance,
885-
noBumping: b.noBumping,
899+
noBumping: b.customFeeRate != nil,
886900
customMuSig2Signer: b.customMuSig2Signer,
887901
}
888902
}

sweepbatcher/sweep_batcher_test.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ func testSweepBatcherBatchCreation(t *testing.T, store testStore,
308308
}
309309

310310
// testFeeBumping tests that sweep is RBFed with slightly higher fee rate after
311-
// each block unless WithNoBumping is passed.
311+
// each block unless WithCustomFeeRate is passed.
312312
func testFeeBumping(t *testing.T, store testStore,
313313
batcherStore testBatcherStore, noFeeBumping bool) {
314314

@@ -324,7 +324,14 @@ func testFeeBumping(t *testing.T, store testStore,
324324
// Disable fee bumping, if requested.
325325
var opts []BatcherOption
326326
if noFeeBumping {
327-
opts = append(opts, WithNoBumping())
327+
customFeeRate := func(ctx context.Context,
328+
swapHash lntypes.Hash) (chainfee.SatPerKWeight, error) {
329+
330+
// Always provide the same value, no bumping.
331+
return test.DefaultMockFee, nil
332+
}
333+
334+
opts = append(opts, WithCustomFeeRate(customFeeRate))
328335
}
329336

330337
batcher := NewBatcher(lnd.WalletKit, lnd.ChainNotifier, lnd.Signer,
@@ -1931,8 +1938,7 @@ func testSweepFetcher(t *testing.T, store testStore,
19311938
feeRate := chainfee.SatPerKWeight(30000)
19321939
amt := btcutil.Amount(1_000_000)
19331940
weight := lntypes.WeightUnit(445) // Weight for 1-to-1 tx.
1934-
bumpedFee := feeRate + 100
1935-
expectedFee := bumpedFee.FeeForWeight(weight)
1941+
expectedFee := feeRate.FeeForWeight(weight)
19361942

19371943
swap := &loopdb.LoopOutContract{
19381944
SwapContract: loopdb.SwapContract{
@@ -1955,7 +1961,6 @@ func testSweepFetcher(t *testing.T, store testStore,
19551961
ConfTarget: 123,
19561962
Timeout: 111,
19571963
SwapInvoicePaymentAddr: *swapPaymentAddr,
1958-
MinFeeRate: feeRate,
19591964
ProtocolVersion: loopdb.ProtocolVersionMuSig2,
19601965
HTLCKeys: htlcKeys,
19611966
HTLC: *htlc,
@@ -1987,9 +1992,16 @@ func testSweepFetcher(t *testing.T, store testStore,
19871992
require.NoError(t, err)
19881993
store.AssertLoopOutStored()
19891994

1995+
customFeeRate := func(ctx context.Context,
1996+
swapHash lntypes.Hash) (chainfee.SatPerKWeight, error) {
1997+
1998+
// Always provide the same value, no bumping.
1999+
return feeRate, nil
2000+
}
2001+
19902002
batcher := NewBatcher(lnd.WalletKit, lnd.ChainNotifier, lnd.Signer,
19912003
testMuSig2SignSweep, testVerifySchnorrSig, lnd.ChainParams,
1992-
batcherStore, sweepFetcher)
2004+
batcherStore, sweepFetcher, WithCustomFeeRate(customFeeRate))
19932005

19942006
var wg sync.WaitGroup
19952007
wg.Add(1)
@@ -2238,7 +2250,7 @@ func TestSweepBatcherBatchCreation(t *testing.T) {
22382250
}
22392251

22402252
// TestFeeBumping tests that sweep is RBFed with slightly higher fee rate after
2241-
// each block unless WithNoBumping is passed.
2253+
// each block unless WithCustomFeeRate is passed.
22422254
func TestFeeBumping(t *testing.T) {
22432255
t.Run("regular", func(t *testing.T) {
22442256
runTests(t, func(t *testing.T, store testStore,
@@ -2248,7 +2260,7 @@ func TestFeeBumping(t *testing.T) {
22482260
})
22492261
})
22502262

2251-
t.Run("WithNoBumping", func(t *testing.T) {
2263+
t.Run("fixed fee rate", func(t *testing.T) {
22522264
runTests(t, func(t *testing.T, store testStore,
22532265
batcherStore testBatcherStore) {
22542266

0 commit comments

Comments
 (0)