cnct: reuse sweep tx logic for commit resolver

Removes duplicate sweep tx code from commit resolver
and delegates generation to UtxoSweeper in the sweep
package.
This commit is contained in:
Joost Jager 2018-09-26 09:46:48 -07:00
parent 7d69df77ed
commit c1d845aa0d
No known key found for this signature in database
GPG Key ID: AE6B0D042C8E38D9
4 changed files with 23 additions and 42 deletions

@ -3,6 +3,7 @@ package contractcourt
import (
"errors"
"fmt"
"github.com/lightningnetwork/lnd/sweep"
"sync"
"sync/atomic"
@ -130,6 +131,9 @@ type ChainArbitratorConfig struct {
// DisableChannel disables a channel, resulting in it not being able to
// forward payments.
DisableChannel func(wire.OutPoint) error
// Sweeper allows resolvers to sweep their final outputs.
Sweeper *sweep.UtxoSweeper
}
// ChainArbitrator is a sub-system that oversees the on-chain resolution of all

@ -5,6 +5,7 @@ import (
"crypto/sha256"
"encoding/binary"
"fmt"
"github.com/lightningnetwork/lnd/sweep"
"io"
"io/ioutil"
@ -1256,46 +1257,16 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) {
// If the sweep transaction isn't already generated, and the remote
// party broadcast the commitment transaction then we'll create it now.
case c.sweepTx == nil && !isLocalCommitTx:
// Now that the commitment transaction has confirmed, we'll
// craft a transaction to sweep this output into the wallet.
signDesc := c.commitResolution.SelfOutputSignDesc
input := sweep.MakeBaseInput(
&c.commitResolution.SelfOutPoint,
lnwallet.CommitmentNoDelay,
&c.commitResolution.SelfOutputSignDesc)
// First, we'll estimate the total weight so we can compute
// fees properly. We'll use a lax estimate, as this output is
// in no immediate danger.
feePerKw, err := c.FeeEstimator.EstimateFeePerKW(6)
if err != nil {
return nil, err
}
log.Debugf("%T(%v): using %v sat/kw for sweep tx", c,
c.chanPoint, int64(feePerKw))
totalWeight := (&lnwallet.TxWeightEstimator{}).
AddP2WKHInput().
AddP2WKHOutput().Weight()
totalFees := feePerKw.FeeForWeight(int64(totalWeight))
sweepAmt := signDesc.Output.Value - int64(totalFees)
c.sweepTx = wire.NewMsgTx(2)
c.sweepTx.AddTxIn(&wire.TxIn{
PreviousOutPoint: c.commitResolution.SelfOutPoint,
})
sweepAddr, err := c.NewSweepAddr()
if err != nil {
return nil, err
}
c.sweepTx.AddTxOut(&wire.TxOut{
PkScript: sweepAddr,
Value: sweepAmt,
})
// With the transaction fully assembled, we can now generate a
// valid witness for the transaction.
signDesc.SigHashes = txscript.NewTxSigHashes(c.sweepTx)
c.sweepTx.TxIn[0].Witness, err = lnwallet.CommitSpendNoDelay(
c.Signer, &signDesc, c.sweepTx,
)
// TODO: Set tx lock time to current block height instead of
// zero. Will be taken care of once sweeper implementation is
// complete.
c.sweepTx, err = c.Sweeper.CreateSweepTx(
[]sweep.Input{&input}, 0)
if err != nil {
return nil, err
}

@ -695,6 +695,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
DisableChannel: func(op wire.OutPoint) error {
return s.announceChanStatus(op, true)
},
Sweeper: sweeper,
}, chanDB)
s.breachArbiter = newBreachArbiter(&BreachConfig{

@ -73,11 +73,17 @@ func (s *UtxoSweeper) CreateSweepTx(inputs []Input,
// outputs.
csvCount := 0
cltvCount := 0
unknownCount := 0
for i := range inputs {
input := inputs[i]
switch input.WitnessType() {
// Outputs on a remote commitment transaction that pay directly
// to us.
case lnwallet.CommitmentNoDelay:
weightEstimate.AddP2WKHInput()
// Outputs on a past commitment transaction that pay directly
// to us.
case lnwallet.CommitmentTimeLock:
@ -113,8 +119,7 @@ func (s *UtxoSweeper) CreateSweepTx(inputs []Input,
cltvCount++
default:
// TODO: Also add non-timelocked outputs
unknownCount++
log.Warnf("kindergarten output in nursery store "+
"contains unexpected witness type: %v",
input.WitnessType())
@ -123,7 +128,7 @@ func (s *UtxoSweeper) CreateSweepTx(inputs []Input,
}
log.Infof("Creating sweep transaction for %v inputs (%v CSV, %v CLTV)",
csvCount+cltvCount, csvCount, cltvCount)
len(inputs)-unknownCount, csvCount, cltvCount)
txWeight := int64(weightEstimate.Weight())
return s.populateSweepTx(txWeight, currentBlockHeight, inputs)