@@ -20,7 +20,18 @@ import (
2020var (
2121 // MinLoopOutPreimageRevealDelta configures the minimum number of
2222 // remaining blocks before htlc expiry required to reveal preimage.
23- MinLoopOutPreimageRevealDelta = int32 (20 )
23+ MinLoopOutPreimageRevealDelta int32 = 20
24+
25+ // DefaultSweepConfTarget is the default confirmation target we'll use
26+ // when sweeping on-chain HTLCs.
27+ DefaultSweepConfTarget int32 = 6
28+
29+ // DefaultSweepConfTargetDelta is the delta of blocks from a Loop Out
30+ // swap's expiration height at which we begin to use the default sweep
31+ // confirmation target.
32+ //
33+ // TODO(wilmer): tune?
34+ DefaultSweepConfTargetDelta int32 = DefaultSweepConfTarget * 2
2435)
2536
2637// loopOutSwap contains all the in-memory state related to a pending loop out
@@ -577,22 +588,29 @@ func (s *loopOutSwap) sweep(ctx context.Context,
577588 htlcValue btcutil.Amount ) error {
578589
579590 witnessFunc := func (sig []byte ) (wire.TxWitness , error ) {
580- return s .htlc .GenSuccessWitness (
581- sig , s .Preimage ,
582- )
591+ return s .htlc .GenSuccessWitness (sig , s .Preimage )
583592 }
584593
585- // Calculate sweep tx fee
594+ // Calculate the transaction fee based on the confirmation target
595+ // required to sweep the HTLC before the timeout. We'll use the
596+ // confirmation target provided by the client unless we've come too
597+ // close to the expiration height, in which case we'll use the default
598+ // if it is better than what the client provided.
599+ confTarget := s .SweepConfTarget
600+ if s .CltvExpiry - s .height >= DefaultSweepConfTargetDelta &&
601+ confTarget > DefaultSweepConfTarget {
602+ confTarget = DefaultSweepConfTarget
603+ }
586604 fee , err := s .sweeper .GetSweepFee (
587- ctx , s .htlc .AddSuccessToEstimator ,
588- s .SweepConfTarget ,
605+ ctx , s .htlc .AddSuccessToEstimator , confTarget ,
589606 )
590607 if err != nil {
591608 return err
592609 }
593610
611+ // Ensure it doesn't exceed our maximum fee allowed.
594612 if fee > s .MaxMinerFee {
595- s .log .Warnf ("Required miner fee %v exceeds max of %v" ,
613+ s .log .Warnf ("Required fee %v exceeds max miner fee of %v" ,
596614 fee , s .MaxMinerFee )
597615
598616 if s .state == loopdb .StatePreimageRevealed {
@@ -608,8 +626,7 @@ func (s *loopOutSwap) sweep(ctx context.Context,
608626
609627 // Create sweep tx.
610628 sweepTx , err := s .sweeper .CreateSweepTx (
611- ctx , s .height , s .htlc , htlcOutpoint ,
612- s .ReceiverKey , witnessFunc ,
629+ ctx , s .height , s .htlc , htlcOutpoint , s .ReceiverKey , witnessFunc ,
613630 htlcValue , fee , s .DestAddr ,
614631 )
615632 if err != nil {
@@ -686,5 +703,11 @@ func validateLoopOutContract(lnd *lndclient.LndServices,
686703 return ErrExpiryTooSoon
687704 }
688705
706+ // Ensure the client has provided a sweep confirmation target that does
707+ // not exceed the height at which we revert back to using the default.
708+ if height + request .SweepConfTarget >= response .expiry - DefaultSweepConfTargetDelta {
709+ return ErrSweepConfTargetTooFar
710+ }
711+
689712 return nil
690713}
0 commit comments