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 ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/lightningnetwork/lnd/sweep"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -130,6 +131,9 @@ type ChainArbitratorConfig struct {
// DisableChannel disables a channel, resulting in it not being able to // DisableChannel disables a channel, resulting in it not being able to
// forward payments. // forward payments.
DisableChannel func(wire.OutPoint) error 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 // ChainArbitrator is a sub-system that oversees the on-chain resolution of all

@ -5,6 +5,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/lightningnetwork/lnd/sweep"
"io" "io"
"io/ioutil" "io/ioutil"
@ -1256,46 +1257,16 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) {
// If the sweep transaction isn't already generated, and the remote // If the sweep transaction isn't already generated, and the remote
// party broadcast the commitment transaction then we'll create it now. // party broadcast the commitment transaction then we'll create it now.
case c.sweepTx == nil && !isLocalCommitTx: case c.sweepTx == nil && !isLocalCommitTx:
// Now that the commitment transaction has confirmed, we'll input := sweep.MakeBaseInput(
// craft a transaction to sweep this output into the wallet. &c.commitResolution.SelfOutPoint,
signDesc := c.commitResolution.SelfOutputSignDesc lnwallet.CommitmentNoDelay,
&c.commitResolution.SelfOutputSignDesc)
// First, we'll estimate the total weight so we can compute // TODO: Set tx lock time to current block height instead of
// fees properly. We'll use a lax estimate, as this output is // zero. Will be taken care of once sweeper implementation is
// in no immediate danger. // complete.
feePerKw, err := c.FeeEstimator.EstimateFeePerKW(6) c.sweepTx, err = c.Sweeper.CreateSweepTx(
if err != nil { []sweep.Input{&input}, 0)
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,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }

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

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