Skip to content

Commit 7763774

Browse files
committed
loopout: wait for full confirmation when sweeping
1 parent c0da5fe commit 7763774

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

client_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ func testLoopOutSuccess(ctx *testContext, amt btcutil.Amount, hash lntypes.Hash,
411411

412412
ctx.AssertRegisterConf(true, 3)
413413

414+
ctx.NotifyConf(sweepTx)
415+
414416
ctx.assertStatus(loopdb.StateSuccess)
415417

416418
ctx.assertStoreFinished(loopdb.StateSuccess)

loopout.go

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -596,33 +596,34 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error {
596596
return nil
597597
}
598598

599-
// Try to spend htlc and continue (rbf) until a spend has confirmed.
600-
spend, err := s.waitForHtlcSpendConfirmedV2(
599+
// Try to spend htlc and continue (rbf) until a spend has fully
600+
// confirmed.
601+
conf, err := s.waitForHtlcSpendConfirmedV2(
601602
globalCtx, *htlcOutpoint, htlcValue,
602603
)
603604
if err != nil {
604605
return err
605606
}
606607

607-
// If spend details are nil, we resolved the swap without waiting for
608-
// its spend, so we can exit.
609-
if spend == nil {
608+
// If conf details are nil, we resolved the swap without waiting for
609+
// its confirmation, so we can exit.
610+
if conf == nil {
610611
return nil
611612
}
612613

613614
// Inspect witness stack to see if it is a success transaction. We
614615
// don't just try to match with the hash of our sweep tx, because it
615616
// may be swept by a different (fee) sweep tx from a previous run.
616617
htlcInput, err := swap.GetTxInputByOutpoint(
617-
spend.Tx, htlcOutpoint,
618+
conf.Tx, htlcOutpoint,
618619
)
619620
if err != nil {
620621
return err
621622
}
622623

623624
sweepSuccessful := s.htlc.IsSuccessWitness(htlcInput.Witness)
624625
if sweepSuccessful {
625-
s.cost.Onchain = spend.OnChainFeePortion
626+
s.cost.Onchain = conf.OnChainFeePortion
626627
s.state = loopdb.StateSuccess
627628
} else {
628629
s.state = loopdb.StateFailSweepTimeout
@@ -1140,10 +1141,12 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
11401141
// sweep or a server revocation tx.
11411142
func (s *loopOutSwap) waitForHtlcSpendConfirmedV2(globalCtx context.Context,
11421143
htlcOutpoint wire.OutPoint, htlcValue btcutil.Amount) (
1143-
*sweepbatcher.SpendDetail, error) {
1144+
*sweepbatcher.ConfDetail, error) {
11441145

11451146
spendChan := make(chan *sweepbatcher.SpendDetail)
11461147
spendErrChan := make(chan error, 1)
1148+
confChan := make(chan *sweepbatcher.ConfDetail, 1)
1149+
confErrChan := make(chan error, 1)
11471150
quitChan := make(chan bool, 1)
11481151

11491152
defer func() {
@@ -1153,6 +1156,8 @@ func (s *loopOutSwap) waitForHtlcSpendConfirmedV2(globalCtx context.Context,
11531156
notifier := sweepbatcher.SpendNotifier{
11541157
SpendChan: spendChan,
11551158
SpendErrChan: spendErrChan,
1159+
ConfChan: confChan,
1160+
ConfErrChan: confErrChan,
11561161
QuitChan: quitChan,
11571162
}
11581163

@@ -1192,15 +1197,28 @@ func (s *loopOutSwap) waitForHtlcSpendConfirmedV2(globalCtx context.Context,
11921197

11931198
for {
11941199
select {
1195-
// Htlc spend, break loop.
1200+
// Htlc spend, but waiting for more confirmations in case of
1201+
// a reorg.
11961202
case spend := <-spendChan:
11971203
s.log.Infof("Htlc spend by tx: %v", spend.Tx.TxHash())
11981204

1199-
return spend, nil
1200-
12011205
// Spend notification error.
12021206
case err := <-spendErrChan:
1203-
return nil, err
1207+
return nil, fmt.Errorf("spend notification error: %w",
1208+
err)
1209+
1210+
// Htlc was spent and the sweep transaction is fully confirmed.
1211+
// Break from loop.
1212+
case conf := <-confChan:
1213+
s.log.Infof("Sweep tx %v fully confirmed in block %d",
1214+
conf.Tx.TxHash(), conf.BlockHeight)
1215+
1216+
return conf, nil
1217+
1218+
// Conf notification error.
1219+
case err := <-confErrChan:
1220+
return nil, fmt.Errorf("conf notification error: %w",
1221+
err)
12041222

12051223
// Receive status updates for our payment so that we can detect
12061224
// whether we've successfully pushed our preimage.

0 commit comments

Comments
 (0)