loop: use default confirmation target for htlc sweep after expiry delta

In this commit, we introduce a delta from the on-chain HTLC's
expiration. Since clients are now able to specify a confirmation target
for the HTLC sweep, it's possible that the sweep doesn't confirm within
the intended target in the event of an increasing demand for block
space. Once the delta from the HTLC's expiration is reached, we'll begin
to use the default sweep confirmation target when sweeping the HTLC,
which should provide a timely confirmation. This is needed because if
the preimage has already been revealed, then we need to make sure we
sweep the HTLC before the server does.
pull/65/head
Wilmer Paulino 5 years ago
parent c16e170338
commit 47321ba4a4
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F

@ -42,6 +42,12 @@ var (
// is too soon for us.
ErrExpiryTooFar = errors.New("swap expiry too far")
// ErrSweepConfTargetTooFar is returned when the client proposes a
// confirmation target to sweep the on-chain HTLC of a Loop Out that is
// beyond the expiration height proposed by the server.
ErrSweepConfTargetTooFar = errors.New("sweep confirmation target is " +
"beyond swap expiration height")
serverRPCTimeout = 30 * time.Second
republishDelay = 10 * time.Second

@ -25,6 +25,13 @@ var (
// DefaultSweepConfTarget is the default confirmation target we'll use
// when sweeping on-chain HTLCs.
DefaultSweepConfTarget int32 = 6
// DefaultSweepConfTargetDelta is the delta of blocks from a Loop Out
// swap's expiration height at which we begin to use the default sweep
// confirmation target.
//
// TODO(wilmer): tune?
DefaultSweepConfTargetDelta int32 = DefaultSweepConfTarget * 2
)
// loopOutSwap contains all the in-memory state related to a pending loop out
@ -581,22 +588,29 @@ func (s *loopOutSwap) sweep(ctx context.Context,
htlcValue btcutil.Amount) error {
witnessFunc := func(sig []byte) (wire.TxWitness, error) {
return s.htlc.GenSuccessWitness(
sig, s.Preimage,
)
return s.htlc.GenSuccessWitness(sig, s.Preimage)
}
// Calculate sweep tx fee
// Calculate the transaction fee based on the confirmation target
// required to sweep the HTLC before the timeout. We'll use the
// confirmation target provided by the client unless we've come too
// close to the expiration height, in which case we'll use the default
// if it is better than what the client provided.
confTarget := s.SweepConfTarget
if s.CltvExpiry-s.height >= DefaultSweepConfTargetDelta &&
confTarget > DefaultSweepConfTarget {
confTarget = DefaultSweepConfTarget
}
fee, err := s.sweeper.GetSweepFee(
ctx, s.htlc.AddSuccessToEstimator,
s.SweepConfTarget,
ctx, s.htlc.AddSuccessToEstimator, confTarget,
)
if err != nil {
return err
}
// Ensure it doesn't exceed our maximum fee allowed.
if fee > s.MaxMinerFee {
s.log.Warnf("Required miner fee %v exceeds max of %v",
s.log.Warnf("Required fee %v exceeds max miner fee of %v",
fee, s.MaxMinerFee)
if s.state == loopdb.StatePreimageRevealed {
@ -612,8 +626,7 @@ func (s *loopOutSwap) sweep(ctx context.Context,
// Create sweep tx.
sweepTx, err := s.sweeper.CreateSweepTx(
ctx, s.height, s.htlc, htlcOutpoint,
s.ReceiverKey, witnessFunc,
ctx, s.height, s.htlc, htlcOutpoint, s.ReceiverKey, witnessFunc,
htlcValue, fee, s.DestAddr,
)
if err != nil {
@ -690,5 +703,11 @@ func validateLoopOutContract(lnd *lndclient.LndServices,
return ErrExpiryTooSoon
}
// Ensure the client has provided a sweep confirmation target that does
// not exceed the height at which we revert back to using the default.
if height+request.SweepConfTarget >= response.expiry-DefaultSweepConfTargetDelta {
return ErrSweepConfTargetTooFar
}
return nil
}

Loading…
Cancel
Save