Skip to content

Commit 1104e92

Browse files
authored
Merge pull request #952 from starius/presigned-fixes2
sweepbatcher: fixes for presigned mode
2 parents fab4a64 + 0dc5d9e commit 1104e92

14 files changed

+603
-391
lines changed

loopdb/sqlc/batch.sql.go

Lines changed: 0 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

loopdb/sqlc/querier.go

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

loopdb/sqlc/queries/batch.sql

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,6 @@ UPDATE sweep_batches SET
3737
last_rbf_sat_per_kw = $6
3838
WHERE id = $1;
3939

40-
-- name: ConfirmBatch :exec
41-
UPDATE
42-
sweep_batches
43-
SET
44-
confirmed = TRUE
45-
WHERE
46-
id = $1;
47-
4840
-- name: UpsertSweep :exec
4941
INSERT INTO sweeps (
5042
swap_hash,

loopout.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,7 @@ func (s *loopOutSwap) waitForHtlcSpendConfirmedV2(globalCtx context.Context,
11471147
quitChan := make(chan bool, 1)
11481148

11491149
defer func() {
1150-
quitChan <- true
1150+
close(quitChan)
11511151
}()
11521152

11531153
notifier := sweepbatcher.SpendNotifier{

loopout_feerate.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/btcsuite/btcd/btcutil"
88
"github.com/btcsuite/btcd/chaincfg"
99
"github.com/btcsuite/btcd/txscript"
10+
"github.com/btcsuite/btcd/wire"
1011
"github.com/lightninglabs/loop/loopdb"
1112
"github.com/lightninglabs/loop/swap"
1213
"github.com/lightninglabs/loop/utils"
@@ -71,7 +72,8 @@ func newLoopOutSweepFeerateProvider(sweeper sweeper,
7172

7273
// GetMinFeeRate returns minimum required feerate for a sweep by swap hash.
7374
func (p *loopOutSweepFeerateProvider) GetMinFeeRate(ctx context.Context,
74-
swapHash lntypes.Hash) (chainfee.SatPerKWeight, error) {
75+
swapHash lntypes.Hash,
76+
_ wire.OutPoint) (chainfee.SatPerKWeight, error) {
7577

7678
_, feeRate, err := p.GetConfTargetAndFeeRate(ctx, swapHash)
7779

sweepbatcher/presigned.go

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,7 @@ func (b *batch) ensurePresigned(ctx context.Context, newSweeps []*sweep,
3636
// presignedTxChecker has methods to check if the inputs are presigned.
3737
type presignedTxChecker interface {
3838
destPkScripter
39-
40-
// SignTx signs an unsigned transaction or returns a pre-signed tx.
41-
// It is only called with loadOnly=true by ensurePresigned.
42-
SignTx(ctx context.Context, primarySweepID wire.OutPoint,
43-
tx *wire.MsgTx, inputAmt btcutil.Amount,
44-
minRelayFee, feeRate chainfee.SatPerKWeight,
45-
loadOnly bool) (*wire.MsgTx, error)
39+
presigner
4640
}
4741

4842
// ensurePresigned checks that there is a presigned transaction spending the
@@ -253,7 +247,7 @@ func (b *batch) presign(ctx context.Context, newSweeps []*sweep) error {
253247

254248
// Cache the destination address.
255249
destAddr, err := getPresignedSweepsDestAddr(
256-
ctx, b.cfg.presignedHelper, b.primarySweepID,
250+
ctx, b.cfg.presignedHelper, primarySweepID,
257251
b.cfg.chainParams,
258252
)
259253
if err != nil {
@@ -289,11 +283,12 @@ func (b *batch) presign(ctx context.Context, newSweeps []*sweep) error {
289283

290284
// presigner tries to presign a batch transaction.
291285
type presigner interface {
292-
// Presign tries to presign a batch transaction. If the method returns
293-
// nil, it is guaranteed that future calls to SignTx on this set of
294-
// sweeps return valid signed transactions.
295-
Presign(ctx context.Context, primarySweepID wire.OutPoint,
296-
tx *wire.MsgTx, inputAmt btcutil.Amount) error
286+
// SignTx signs an unsigned transaction or returns a pre-signed tx.
287+
// It is only called with loadOnly=true by ensurePresigned.
288+
SignTx(ctx context.Context, primarySweepID wire.OutPoint,
289+
tx *wire.MsgTx, inputAmt btcutil.Amount,
290+
minRelayFee, feeRate chainfee.SatPerKWeight,
291+
loadOnly bool) (*wire.MsgTx, error)
297292
}
298293

299294
// presign tries to presign batch sweep transactions of the sweeps. It signs
@@ -372,7 +367,14 @@ func presign(ctx context.Context, presigner presigner, destAddr btcutil.Address,
372367
}
373368

374369
// Try to presign this transaction.
375-
err = presigner.Presign(ctx, primarySweepID, tx, batchAmt)
370+
const (
371+
loadOnly = false
372+
minRelayFee = chainfee.AbsoluteFeePerKwFloor
373+
)
374+
_, err = presigner.SignTx(
375+
ctx, primarySweepID, tx, batchAmt, minRelayFee, fr,
376+
loadOnly,
377+
)
376378
if err != nil {
377379
return fmt.Errorf("failed to presign unsigned tx %v "+
378380
"for feeRate %v: %w", tx.TxHash(), fr, err)
@@ -407,9 +409,16 @@ func (b *batch) publishPresigned(ctx context.Context) (btcutil.Amount, error,
407409
}
408410
}
409411

412+
// Determine the current minimum relay fee based on our chain backend.
413+
minRelayFee, err := b.wallet.MinRelayFee(ctx)
414+
if err != nil {
415+
return 0, fmt.Errorf("failed to get minRelayFee: %w", err),
416+
false
417+
}
418+
410419
// Cache current height and desired feerate of the batch.
411420
currentHeight := b.currentHeight
412-
feeRate := b.rbfCache.FeeRate
421+
feeRate := max(b.rbfCache.FeeRate, minRelayFee)
413422

414423
// Append this sweep to an array of sweeps. This is needed to keep the
415424
// order of sweeps stored, as iterating the sweeps map does not
@@ -447,13 +456,6 @@ func (b *batch) publishPresigned(ctx context.Context) (btcutil.Amount, error,
447456
batchAmt += sweep.value
448457
}
449458

450-
// Determine the current minimum relay fee based on our chain backend.
451-
minRelayFee, err := b.wallet.MinRelayFee(ctx)
452-
if err != nil {
453-
return 0, fmt.Errorf("failed to get minRelayFee: %w", err),
454-
false
455-
}
456-
457459
// Get a pre-signed transaction.
458460
const loadOnly = false
459461
signedTx, err := b.cfg.presignedHelper.SignTx(
@@ -508,6 +510,9 @@ func (b *batch) publishPresigned(ctx context.Context) (btcutil.Amount, error,
508510
b.batchTxid = &txHash
509511
b.batchPkScript = tx.TxOut[0].PkScript
510512

513+
// Update cached FeeRate not to broadcast a tx with lower feeRate.
514+
b.rbfCache.FeeRate = max(b.rbfCache.FeeRate, signedFeeRate)
515+
511516
return fee, nil, true
512517
}
513518

@@ -599,7 +604,7 @@ func CheckSignedTx(unsignedTx, signedTx *wire.MsgTx, inputAmt btcutil.Amount,
599604
unsignedOut := unsignedTx.TxOut[0]
600605
signedOut := signedTx.TxOut[0]
601606
if !bytes.Equal(unsignedOut.PkScript, signedOut.PkScript) {
602-
return fmt.Errorf("mismatch of output pkScript: %v, %v",
607+
return fmt.Errorf("mismatch of output pkScript: %x, %x",
603608
unsignedOut.PkScript, signedOut.PkScript)
604609
}
605610

sweepbatcher/presigned_test.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -612,24 +612,30 @@ type mockPresigner struct {
612612
failAt int
613613
}
614614

615-
// Presign memorizes the value of the output and fails if the number of
615+
// SignTx memorizes the value of the output and fails if the number of
616616
// calls previously made is failAt.
617-
func (p *mockPresigner) Presign(ctx context.Context,
618-
primarySweepID wire.OutPoint, tx *wire.MsgTx,
619-
inputAmt btcutil.Amount) error {
617+
func (p *mockPresigner) SignTx(ctx context.Context,
618+
primarySweepID wire.OutPoint, tx *wire.MsgTx, inputAmt btcutil.Amount,
619+
minRelayFee, feeRate chainfee.SatPerKWeight,
620+
loadOnly bool) (*wire.MsgTx, error) {
621+
622+
if ctx.Err() != nil {
623+
return nil, ctx.Err()
624+
}
620625

621626
if !hasInput(tx, primarySweepID) {
622-
return fmt.Errorf("primarySweepID %v not in tx", primarySweepID)
627+
return nil, fmt.Errorf("primarySweepID %v not in tx",
628+
primarySweepID)
623629
}
624630

625631
if len(p.outputs)+1 == p.failAt {
626-
return fmt.Errorf("test error in Presign")
632+
return nil, fmt.Errorf("test error in SignTx")
627633
}
628634

629635
p.outputs = append(p.outputs, btcutil.Amount(tx.TxOut[0].Value))
630636
p.lockTimes = append(p.lockTimes, tx.LockTime)
631637

632-
return nil
638+
return tx, nil
633639
}
634640

635641
// TestPresign checks that function presign presigns correct set of transactions

sweepbatcher/store.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ import (
1616
// Querier is the interface that contains all the queries generated
1717
// by sqlc for sweep batcher.
1818
type Querier interface {
19-
// ConfirmBatch confirms a batch by setting the state to confirmed.
20-
ConfirmBatch(ctx context.Context, id int32) error
21-
2219
// GetBatchSweeps fetches all the sweeps that are part a batch.
2320
GetBatchSweeps(ctx context.Context, batchID int32) (
2421
[]sqlc.Sweep, error)
@@ -124,11 +121,6 @@ func (s *SQLStore) UpdateSweepBatch(ctx context.Context, batch *dbBatch) error {
124121
return s.baseDb.UpdateBatch(ctx, batchToUpdateArgs(*batch))
125122
}
126123

127-
// ConfirmBatch confirms a batch by setting the state to confirmed.
128-
func (s *SQLStore) ConfirmBatch(ctx context.Context, id int32) error {
129-
return s.baseDb.ConfirmBatch(ctx, id)
130-
}
131-
132124
// FetchBatchSweeps fetches all the sweeps that are part a batch.
133125
func (s *SQLStore) FetchBatchSweeps(ctx context.Context, id int32) (
134126
[]*dbSweep, error) {
@@ -201,7 +193,7 @@ type dbBatch struct {
201193
// ID is the unique identifier of the batch.
202194
ID int32
203195

204-
// Confirmed is set when the batch is fully confirmed.
196+
// Confirmed is set when the batch is reorg-safely confirmed.
205197
Confirmed bool
206198

207199
// BatchTxid is the txid of the batch transaction.
@@ -236,7 +228,7 @@ type dbSweep struct {
236228
// Amount is the amount of the sweep.
237229
Amount btcutil.Amount
238230

239-
// Completed indicates whether this sweep is completed.
231+
// Completed indicates whether this sweep is fully-confirmed.
240232
Completed bool
241233
}
242234

sweepbatcher/store_mock.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,6 @@ func (s *StoreMock) UpdateSweepBatch(ctx context.Context,
7777
return nil
7878
}
7979

80-
// ConfirmBatch confirms a batch.
81-
func (s *StoreMock) ConfirmBatch(ctx context.Context, id int32) error {
82-
s.mu.Lock()
83-
defer s.mu.Unlock()
84-
85-
batch, ok := s.batches[id]
86-
if !ok {
87-
return errors.New("batch not found")
88-
}
89-
90-
batch.Confirmed = true
91-
s.batches[batch.ID] = batch
92-
93-
return nil
94-
}
95-
9680
// FetchBatchSweeps fetches all the sweeps that belong to a batch.
9781
func (s *StoreMock) FetchBatchSweeps(ctx context.Context,
9882
id int32) ([]*dbSweep, error) {

0 commit comments

Comments
 (0)