multi: move Input interface and related code
This commit is a step to split the lnwallet package. It puts the Input interface and implementations in a separate package along with all their dependencies from lnwallet.
This commit is contained in:
66 files changed
+811
-689
No files matched your search
-179
@@ -1,179 +0,0 @@
|
||||
package sweep
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
// Input represents an abstract UTXO which is to be spent using a sweeping
|
||||
// transaction. The method provided give the caller all information needed to
|
||||
// construct a valid input within a sweeping transaction to sweep this
|
||||
// lingering UTXO.
|
||||
type Input interface {
|
||||
// Outpoint returns the reference to the output being spent, used to
|
||||
// construct the corresponding transaction input.
|
||||
OutPoint() *wire.OutPoint
|
||||
|
||||
// WitnessType returns an enum specifying the type of witness that must
|
||||
// be generated in order to spend this output.
|
||||
WitnessType() lnwallet.WitnessType
|
||||
|
||||
// SignDesc returns a reference to a spendable output's sign
|
||||
// descriptor, which is used during signing to compute a valid witness
|
||||
// that spends this output.
|
||||
SignDesc() *lnwallet.SignDescriptor
|
||||
|
||||
// CraftInputScript returns a valid set of input scripts allowing this
|
||||
// output to be spent. The returns input scripts should target the
|
||||
// input at location txIndex within the passed transaction. The input
|
||||
// scripts generated by this method support spending p2wkh, p2wsh, and
|
||||
// also nested p2sh outputs.
|
||||
CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
|
||||
hashCache *txscript.TxSigHashes,
|
||||
txinIdx int) (*lnwallet.InputScript, error)
|
||||
|
||||
// BlocksToMaturity returns the relative timelock, as a number of
|
||||
// blocks, that must be built on top of the confirmation height before
|
||||
// the output can be spent. For non-CSV locked inputs this is always
|
||||
// zero.
|
||||
BlocksToMaturity() uint32
|
||||
|
||||
// HeightHint returns the minimum height at which a confirmed spending
|
||||
// tx can occur.
|
||||
HeightHint() uint32
|
||||
}
|
||||
|
||||
type inputKit struct {
|
||||
outpoint wire.OutPoint
|
||||
witnessType lnwallet.WitnessType
|
||||
signDesc lnwallet.SignDescriptor
|
||||
heightHint uint32
|
||||
}
|
||||
|
||||
// OutPoint returns the breached output's identifier that is to be included as
|
||||
// a transaction input.
|
||||
func (i *inputKit) OutPoint() *wire.OutPoint {
|
||||
return &i.outpoint
|
||||
}
|
||||
|
||||
// WitnessType returns the type of witness that must be generated to spend the
|
||||
// breached output.
|
||||
func (i *inputKit) WitnessType() lnwallet.WitnessType {
|
||||
return i.witnessType
|
||||
}
|
||||
|
||||
// SignDesc returns the breached output's SignDescriptor, which is used during
|
||||
// signing to compute the witness.
|
||||
func (i *inputKit) SignDesc() *lnwallet.SignDescriptor {
|
||||
return &i.signDesc
|
||||
}
|
||||
|
||||
// HeightHint returns the minimum height at which a confirmed spending
|
||||
// tx can occur.
|
||||
func (i *inputKit) HeightHint() uint32 {
|
||||
return i.heightHint
|
||||
}
|
||||
|
||||
// BaseInput contains all the information needed to sweep a basic output
|
||||
// (CSV/CLTV/no time lock)
|
||||
type BaseInput struct {
|
||||
inputKit
|
||||
}
|
||||
|
||||
// MakeBaseInput assembles a new BaseInput that can be used to construct a
|
||||
// sweep transaction.
|
||||
func MakeBaseInput(outpoint *wire.OutPoint, witnessType lnwallet.WitnessType,
|
||||
signDescriptor *lnwallet.SignDescriptor, heightHint uint32) BaseInput {
|
||||
|
||||
return BaseInput{
|
||||
inputKit{
|
||||
outpoint: *outpoint,
|
||||
witnessType: witnessType,
|
||||
signDesc: *signDescriptor,
|
||||
heightHint: heightHint,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CraftInputScript returns a valid set of input scripts allowing this output
|
||||
// to be spent. The returns input scripts should target the input at location
|
||||
// txIndex within the passed transaction. The input scripts generated by this
|
||||
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
|
||||
func (bi *BaseInput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
|
||||
hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) {
|
||||
|
||||
witnessFunc := bi.witnessType.GenWitnessFunc(
|
||||
signer, bi.SignDesc(),
|
||||
)
|
||||
|
||||
return witnessFunc(txn, hashCache, txinIdx)
|
||||
}
|
||||
|
||||
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
|
||||
// must be built on top of the confirmation height before the output can be
|
||||
// spent. For non-CSV locked inputs this is always zero.
|
||||
func (bi *BaseInput) BlocksToMaturity() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input
|
||||
// is expected to reside on the commitment tx of the remote party and should
|
||||
// not be a second level tx output.
|
||||
type HtlcSucceedInput struct {
|
||||
inputKit
|
||||
|
||||
preimage []byte
|
||||
}
|
||||
|
||||
// MakeHtlcSucceedInput assembles a new redeem input that can be used to
|
||||
// construct a sweep transaction.
|
||||
func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
|
||||
signDescriptor *lnwallet.SignDescriptor,
|
||||
preimage []byte, heightHint uint32) HtlcSucceedInput {
|
||||
|
||||
return HtlcSucceedInput{
|
||||
inputKit: inputKit{
|
||||
outpoint: *outpoint,
|
||||
witnessType: lnwallet.HtlcAcceptedRemoteSuccess,
|
||||
signDesc: *signDescriptor,
|
||||
heightHint: heightHint,
|
||||
},
|
||||
preimage: preimage,
|
||||
}
|
||||
}
|
||||
|
||||
// CraftInputScript returns a valid set of input scripts allowing this output
|
||||
// to be spent. The returns input scripts should target the input at location
|
||||
// txIndex within the passed transaction. The input scripts generated by this
|
||||
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
|
||||
func (h *HtlcSucceedInput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
|
||||
hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) {
|
||||
|
||||
desc := h.signDesc
|
||||
desc.SigHashes = hashCache
|
||||
desc.InputIndex = txinIdx
|
||||
|
||||
witness, err := lnwallet.SenderHtlcSpendRedeem(
|
||||
signer, &desc, txn, h.preimage,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &lnwallet.InputScript{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
|
||||
// must be built on top of the confirmation height before the output can be
|
||||
// spent.
|
||||
func (h *HtlcSucceedInput) BlocksToMaturity() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Compile-time constraints to ensure each input struct implement the Input
|
||||
// interface.
|
||||
var _ Input = (*BaseInput)(nil)
|
||||
var _ Input = (*HtlcSucceedInput)(nil)
|
||||
+7
-6
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
@@ -39,7 +40,7 @@ type pendingInput struct {
|
||||
|
||||
// input is the original struct that contains the input and sign
|
||||
// descriptor.
|
||||
input Input
|
||||
input input.Input
|
||||
|
||||
// ntfnRegCancel is populated with a function that cancels the chain
|
||||
// notifier spend registration.
|
||||
@@ -111,7 +112,7 @@ type UtxoSweeperConfig struct {
|
||||
|
||||
// Signer is used by the sweeper to generate valid witnesses at the
|
||||
// time the incubated outputs need to be spent.
|
||||
Signer lnwallet.Signer
|
||||
Signer input.Signer
|
||||
|
||||
// SweepTxConfTarget assigns a confirmation target for sweep txes on
|
||||
// which the fee calculation will be based.
|
||||
@@ -148,7 +149,7 @@ type Result struct {
|
||||
// sweepInputMessage structs are used in the internal channel between the
|
||||
// SweepInput call and the sweeper main loop.
|
||||
type sweepInputMessage struct {
|
||||
input Input
|
||||
input input.Input
|
||||
resultChan chan Result
|
||||
}
|
||||
|
||||
@@ -256,7 +257,7 @@ func (s *UtxoSweeper) Stop() error {
|
||||
// NOTE: Extreme care needs to be taken that input isn't changed externally.
|
||||
// Because it is an interface and we don't know what is exactly behind it, we
|
||||
// cannot make a local copy in sweeper.
|
||||
func (s *UtxoSweeper) SweepInput(input Input) (chan Result, error) {
|
||||
func (s *UtxoSweeper) SweepInput(input input.Input) (chan Result, error) {
|
||||
if input == nil || input.OutPoint() == nil || input.SignDesc() == nil {
|
||||
return nil, errors.New("nil input received")
|
||||
}
|
||||
@@ -550,7 +551,7 @@ func (s *UtxoSweeper) getInputLists(currentHeight int32,
|
||||
// contain inputs that failed before. Therefore we also add sets
|
||||
// consisting of only new inputs to the list, to make sure that new
|
||||
// inputs are given a good, isolated chance of being published.
|
||||
var newInputs, retryInputs []Input
|
||||
var newInputs, retryInputs []input.Input
|
||||
for _, input := range s.pendingInputs {
|
||||
// Skip inputs that have a minimum publish height that is not
|
||||
// yet reached.
|
||||
@@ -750,7 +751,7 @@ func (s *UtxoSweeper) waitForSpend(outpoint wire.OutPoint,
|
||||
// - Make handling re-orgs easier.
|
||||
// - Thwart future possible fee sniping attempts.
|
||||
// - Make us blend in with the bitcoind wallet.
|
||||
func (s *UtxoSweeper) CreateSweepTx(inputs []Input, feePref FeePreference,
|
||||
func (s *UtxoSweeper) CreateSweepTx(inputs []input.Input, feePref FeePreference,
|
||||
currentBlockHeight uint32) (*wire.MsgTx, error) {
|
||||
|
||||
feePerKw, err := DetermineFeePerKw(s.cfg.FeeEstimator, feePref)
|
||||
|
||||
+12
-12
@@ -12,8 +12,8 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/build"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -38,7 +38,7 @@ type sweeperTestContext struct {
|
||||
}
|
||||
|
||||
var (
|
||||
spendableInputs []*BaseInput
|
||||
spendableInputs []*input.BaseInput
|
||||
testInputCount int
|
||||
|
||||
testPubKey, _ = btcec.ParsePubKey([]byte{
|
||||
@@ -53,17 +53,17 @@ var (
|
||||
}, btcec.S256())
|
||||
)
|
||||
|
||||
func createTestInput(value int64, witnessType lnwallet.WitnessType) BaseInput {
|
||||
func createTestInput(value int64, witnessType input.WitnessType) input.BaseInput {
|
||||
hash := chainhash.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
byte(testInputCount)}
|
||||
|
||||
input := MakeBaseInput(
|
||||
input := input.MakeBaseInput(
|
||||
&wire.OutPoint{
|
||||
Hash: hash,
|
||||
},
|
||||
witnessType,
|
||||
&lnwallet.SignDescriptor{
|
||||
&input.SignDescriptor{
|
||||
Output: &wire.TxOut{
|
||||
Value: value,
|
||||
},
|
||||
@@ -83,7 +83,7 @@ func init() {
|
||||
// Create a set of test spendable inputs.
|
||||
for i := 0; i < 5; i++ {
|
||||
input := createTestInput(int64(10000+i*500),
|
||||
lnwallet.CommitmentTimeLock)
|
||||
input.CommitmentTimeLock)
|
||||
|
||||
spendableInputs = append(spendableInputs, &input)
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func TestDust(t *testing.T) {
|
||||
// Create an input so that the output after paying fees is still
|
||||
// positive (400 sat), but less than the dust limit (537 sat) for the
|
||||
// sweep tx output script (P2WPKH).
|
||||
dustInput := createTestInput(5260, lnwallet.CommitmentTimeLock)
|
||||
dustInput := createTestInput(5260, input.CommitmentTimeLock)
|
||||
|
||||
_, err := ctx.sweeper.SweepInput(&dustInput)
|
||||
if err != nil {
|
||||
@@ -314,7 +314,7 @@ func TestDust(t *testing.T) {
|
||||
// that the sweep output will not be relayed and not generate the tx.
|
||||
|
||||
// Sweep another input that brings the tx output above the dust limit.
|
||||
largeInput := createTestInput(100000, lnwallet.CommitmentTimeLock)
|
||||
largeInput := createTestInput(100000, input.CommitmentTimeLock)
|
||||
|
||||
_, err = ctx.sweeper.SweepInput(&largeInput)
|
||||
if err != nil {
|
||||
@@ -344,7 +344,7 @@ func TestNegativeInput(t *testing.T) {
|
||||
|
||||
// Sweep an input large enough to cover fees, so in any case the tx
|
||||
// output will be above the dust limit.
|
||||
largeInput := createTestInput(100000, lnwallet.CommitmentNoDelay)
|
||||
largeInput := createTestInput(100000, input.CommitmentNoDelay)
|
||||
largeInputResult, err := ctx.sweeper.SweepInput(&largeInput)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -353,7 +353,7 @@ func TestNegativeInput(t *testing.T) {
|
||||
// Sweep an additional input with a negative net yield. The weight of
|
||||
// the HtlcAcceptedRemoteSuccess input type adds more in fees than its
|
||||
// value at the current fee level.
|
||||
negInput := createTestInput(2900, lnwallet.HtlcOfferedRemoteTimeout)
|
||||
negInput := createTestInput(2900, input.HtlcOfferedRemoteTimeout)
|
||||
negInputResult, err := ctx.sweeper.SweepInput(&negInput)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -361,7 +361,7 @@ func TestNegativeInput(t *testing.T) {
|
||||
|
||||
// Sweep a third input that has a smaller output than the previous one,
|
||||
// but yields positively because of its lower weight.
|
||||
positiveInput := createTestInput(2800, lnwallet.CommitmentNoDelay)
|
||||
positiveInput := createTestInput(2800, input.CommitmentNoDelay)
|
||||
positiveInputResult, err := ctx.sweeper.SweepInput(&positiveInput)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -390,7 +390,7 @@ func TestNegativeInput(t *testing.T) {
|
||||
ctx.estimator.updateFees(1000, 1000)
|
||||
|
||||
// Create another large input
|
||||
secondLargeInput := createTestInput(100000, lnwallet.CommitmentNoDelay)
|
||||
secondLargeInput := createTestInput(100000, input.CommitmentNoDelay)
|
||||
secondLargeInputResult, err := ctx.sweeper.SweepInput(&secondLargeInput)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -21,15 +21,15 @@ type mockSigner struct {
|
||||
}
|
||||
|
||||
func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx,
|
||||
signDesc *lnwallet.SignDescriptor) ([]byte, error) {
|
||||
signDesc *input.SignDescriptor) ([]byte, error) {
|
||||
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx,
|
||||
signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) {
|
||||
signDesc *input.SignDescriptor) (*input.Script, error) {
|
||||
|
||||
return &lnwallet.InputScript{}, nil
|
||||
return &input.Script{}, nil
|
||||
}
|
||||
|
||||
// MockNotifier simulates the chain notifier for test purposes. This type is
|
||||
|
||||
+38
-37
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcwallet/wallet/txrules"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
@@ -21,21 +22,21 @@ var (
|
||||
|
||||
// inputSet is a set of inputs that can be used as the basis to generate a tx
|
||||
// on.
|
||||
type inputSet []Input
|
||||
type inputSet []input.Input
|
||||
|
||||
// generateInputPartitionings goes through all given inputs and constructs sets
|
||||
// of inputs that can be used to generate a sensible transaction. Each set
|
||||
// contains up to the configured maximum number of inputs. Negative yield
|
||||
// inputs are skipped. No input sets with a total value after fees below the
|
||||
// dust limit are returned.
|
||||
func generateInputPartitionings(sweepableInputs []Input,
|
||||
func generateInputPartitionings(sweepableInputs []input.Input,
|
||||
relayFeePerKW, feePerKW lnwallet.SatPerKWeight,
|
||||
maxInputsPerTx int) ([]inputSet, error) {
|
||||
|
||||
// Calculate dust limit based on the P2WPKH output script of the sweep
|
||||
// txes.
|
||||
dustLimit := txrules.GetDustThreshold(
|
||||
lnwallet.P2WPKHSize,
|
||||
input.P2WPKHSize,
|
||||
btcutil.Amount(relayFeePerKW.FeePerKVByte()),
|
||||
)
|
||||
|
||||
@@ -113,10 +114,10 @@ func generateInputPartitionings(sweepableInputs []Input,
|
||||
// up the utxo set even if it costs us some fees up front. In the spirit of
|
||||
// minimizing any negative externalities we cause for the Bitcoin system as a
|
||||
// whole.
|
||||
func getPositiveYieldInputs(sweepableInputs []Input, maxInputs int,
|
||||
func getPositiveYieldInputs(sweepableInputs []input.Input, maxInputs int,
|
||||
feePerKW lnwallet.SatPerKWeight) (int, btcutil.Amount) {
|
||||
|
||||
var weightEstimate lnwallet.TxWeightEstimator
|
||||
var weightEstimate input.TxWeightEstimator
|
||||
|
||||
// Add the sweep tx output to the weight estimate.
|
||||
weightEstimate.AddP2WKHOutput()
|
||||
@@ -166,9 +167,9 @@ func getPositiveYieldInputs(sweepableInputs []Input, maxInputs int,
|
||||
}
|
||||
|
||||
// createSweepTx builds a signed tx spending the inputs to a the output script.
|
||||
func createSweepTx(inputs []Input, outputPkScript []byte,
|
||||
func createSweepTx(inputs []input.Input, outputPkScript []byte,
|
||||
currentBlockHeight uint32, feePerKw lnwallet.SatPerKWeight,
|
||||
signer lnwallet.Signer) (*wire.MsgTx, error) {
|
||||
signer input.Signer) (*wire.MsgTx, error) {
|
||||
|
||||
inputs, txWeight, csvCount, cltvCount := getWeightEstimate(inputs)
|
||||
|
||||
@@ -222,7 +223,7 @@ func createSweepTx(inputs []Input, outputPkScript []byte,
|
||||
|
||||
// With all the inputs in place, use each output's unique input script
|
||||
// function to generate the final witness required for spending.
|
||||
addInputScript := func(idx int, tso Input) error {
|
||||
addInputScript := func(idx int, tso input.Input) error {
|
||||
inputScript, err := tso.CraftInputScript(
|
||||
signer, sweepTx, hashCache, idx,
|
||||
)
|
||||
@@ -254,62 +255,62 @@ func createSweepTx(inputs []Input, outputPkScript []byte,
|
||||
// the given input if it would be included in a tx. We also return if the
|
||||
// output itself is a nested p2sh output, if so then we need to take into
|
||||
// account the extra sigScript data size.
|
||||
func getInputWitnessSizeUpperBound(input Input) (int, bool, error) {
|
||||
switch input.WitnessType() {
|
||||
func getInputWitnessSizeUpperBound(inp input.Input) (int, bool, error) {
|
||||
switch inp.WitnessType() {
|
||||
|
||||
// Outputs on a remote commitment transaction that pay directly to us.
|
||||
case lnwallet.WitnessKeyHash:
|
||||
case input.WitnessKeyHash:
|
||||
fallthrough
|
||||
case lnwallet.CommitmentNoDelay:
|
||||
return lnwallet.P2WKHWitnessSize, false, nil
|
||||
case input.CommitmentNoDelay:
|
||||
return input.P2WKHWitnessSize, false, nil
|
||||
|
||||
// Outputs on a past commitment transaction that pay directly
|
||||
// to us.
|
||||
case lnwallet.CommitmentTimeLock:
|
||||
return lnwallet.ToLocalTimeoutWitnessSize, false, nil
|
||||
case input.CommitmentTimeLock:
|
||||
return input.ToLocalTimeoutWitnessSize, false, nil
|
||||
|
||||
// Outgoing second layer HTLC's that have confirmed within the
|
||||
// chain, and the output they produced is now mature enough to
|
||||
// sweep.
|
||||
case lnwallet.HtlcOfferedTimeoutSecondLevel:
|
||||
return lnwallet.ToLocalTimeoutWitnessSize, false, nil
|
||||
case input.HtlcOfferedTimeoutSecondLevel:
|
||||
return input.ToLocalTimeoutWitnessSize, false, nil
|
||||
|
||||
// Incoming second layer HTLC's that have confirmed within the
|
||||
// chain, and the output they produced is now mature enough to
|
||||
// sweep.
|
||||
case lnwallet.HtlcAcceptedSuccessSecondLevel:
|
||||
return lnwallet.ToLocalTimeoutWitnessSize, false, nil
|
||||
case input.HtlcAcceptedSuccessSecondLevel:
|
||||
return input.ToLocalTimeoutWitnessSize, false, nil
|
||||
|
||||
// An HTLC on the commitment transaction of the remote party,
|
||||
// that has had its absolute timelock expire.
|
||||
case lnwallet.HtlcOfferedRemoteTimeout:
|
||||
return lnwallet.AcceptedHtlcTimeoutWitnessSize, false, nil
|
||||
case input.HtlcOfferedRemoteTimeout:
|
||||
return input.AcceptedHtlcTimeoutWitnessSize, false, nil
|
||||
|
||||
// An HTLC on the commitment transaction of the remote party,
|
||||
// that can be swept with the preimage.
|
||||
case lnwallet.HtlcAcceptedRemoteSuccess:
|
||||
return lnwallet.OfferedHtlcSuccessWitnessSize, false, nil
|
||||
case input.HtlcAcceptedRemoteSuccess:
|
||||
return input.OfferedHtlcSuccessWitnessSize, false, nil
|
||||
|
||||
// A nested P2SH input that has a p2wkh witness script. We'll mark this
|
||||
// as nested P2SH so the caller can estimate the weight properly
|
||||
// including the sigScript.
|
||||
case lnwallet.NestedWitnessKeyHash:
|
||||
return lnwallet.P2WKHWitnessSize, true, nil
|
||||
case input.NestedWitnessKeyHash:
|
||||
return input.P2WKHWitnessSize, true, nil
|
||||
}
|
||||
|
||||
return 0, false, fmt.Errorf("unexpected witness type: %v",
|
||||
input.WitnessType())
|
||||
inp.WitnessType())
|
||||
}
|
||||
|
||||
// getWeightEstimate returns a weight estimate for the given inputs.
|
||||
// Additionally, it returns counts for the number of csv and cltv inputs.
|
||||
func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) {
|
||||
func getWeightEstimate(inputs []input.Input) ([]input.Input, int64, int, int) {
|
||||
// We initialize a weight estimator so we can accurately asses the
|
||||
// amount of fees we need to pay for this sweep transaction.
|
||||
//
|
||||
// TODO(roasbeef): can be more intelligent about buffering outputs to
|
||||
// be more efficient on-chain.
|
||||
var weightEstimate lnwallet.TxWeightEstimator
|
||||
var weightEstimate input.TxWeightEstimator
|
||||
|
||||
// Our sweep transaction will pay to a single segwit p2wkh address,
|
||||
// ensure it contributes to our weight estimate.
|
||||
@@ -319,16 +320,16 @@ func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) {
|
||||
// weight of its witness, and add it to the proper set of spendable
|
||||
// outputs.
|
||||
var (
|
||||
sweepInputs []Input
|
||||
sweepInputs []input.Input
|
||||
csvCount, cltvCount int
|
||||
)
|
||||
for i := range inputs {
|
||||
input := inputs[i]
|
||||
inp := inputs[i]
|
||||
|
||||
// For fee estimation purposes, we'll now attempt to obtain an
|
||||
// upper bound on the weight this input will add when fully
|
||||
// populated.
|
||||
size, isNestedP2SH, err := getInputWitnessSizeUpperBound(input)
|
||||
size, isNestedP2SH, err := getInputWitnessSizeUpperBound(inp)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
|
||||
@@ -345,15 +346,15 @@ func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) {
|
||||
weightEstimate.AddWitnessInput(size)
|
||||
}
|
||||
|
||||
switch input.WitnessType() {
|
||||
case lnwallet.CommitmentTimeLock,
|
||||
lnwallet.HtlcOfferedTimeoutSecondLevel,
|
||||
lnwallet.HtlcAcceptedSuccessSecondLevel:
|
||||
switch inp.WitnessType() {
|
||||
case input.CommitmentTimeLock,
|
||||
input.HtlcOfferedTimeoutSecondLevel,
|
||||
input.HtlcAcceptedSuccessSecondLevel:
|
||||
csvCount++
|
||||
case lnwallet.HtlcOfferedRemoteTimeout:
|
||||
case input.HtlcOfferedRemoteTimeout:
|
||||
cltvCount++
|
||||
}
|
||||
sweepInputs = append(sweepInputs, input)
|
||||
sweepInputs = append(sweepInputs, inp)
|
||||
}
|
||||
|
||||
txWeight := int64(weightEstimate.Weight())
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
@@ -152,7 +153,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
|
||||
deliveryAddr btcutil.Address, coinSelectLocker CoinSelectionLocker,
|
||||
utxoSource UtxoSource, outpointLocker OutpointLocker,
|
||||
feeEstimator lnwallet.FeeEstimator,
|
||||
signer lnwallet.Signer) (*WalletSweepPackage, error) {
|
||||
signer input.Signer) (*WalletSweepPackage, error) {
|
||||
|
||||
// TODO(roasbeef): turn off ATPL as well when available?
|
||||
|
||||
@@ -206,7 +207,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
|
||||
// Now that we've locked all the potential outputs to sweep, we'll
|
||||
// assemble an input for each of them, so we can hand it off to the
|
||||
// sweeper to generate and sign a transaction for us.
|
||||
var inputsToSweep []Input
|
||||
var inputsToSweep []input.Input
|
||||
for _, output := range allOutputs {
|
||||
// We'll consult the utxoSource for information concerning this
|
||||
// outpoint, we'll need to properly populate a signDescriptor
|
||||
@@ -222,7 +223,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
|
||||
// we only need to populate the output value and output script.
|
||||
// The rest of the items will be populated internally within
|
||||
// the sweeper via the witness generation function.
|
||||
signDesc := &lnwallet.SignDescriptor{
|
||||
signDesc := &input.SignDescriptor{
|
||||
Output: outputInfo,
|
||||
HashType: txscript.SigHashAll,
|
||||
}
|
||||
@@ -232,18 +233,18 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
|
||||
// Based on the output type, we'll map it to the proper witness
|
||||
// type so we can generate the set of input scripts needed to
|
||||
// sweep the output.
|
||||
var witnessType lnwallet.WitnessType
|
||||
var witnessType input.WitnessType
|
||||
switch {
|
||||
|
||||
// If this is a p2wkh output, then we'll assume it's a witness
|
||||
// key hash witness type.
|
||||
case txscript.IsPayToWitnessPubKeyHash(pkScript):
|
||||
witnessType = lnwallet.WitnessKeyHash
|
||||
witnessType = input.WitnessKeyHash
|
||||
|
||||
// If this is a p2sh output, then as since it's under control
|
||||
// of the wallet, we'll assume it's a nested p2sh output.
|
||||
case txscript.IsPayToScriptHash(pkScript):
|
||||
witnessType = lnwallet.NestedWitnessKeyHash
|
||||
witnessType = input.NestedWitnessKeyHash
|
||||
|
||||
// All other output types we count as unknown and will fail to
|
||||
// sweep.
|
||||
@@ -257,7 +258,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
|
||||
// Now that we've constructed the items required, we'll make an
|
||||
// input which can be passed to the sweeper for ultimate
|
||||
// sweeping.
|
||||
input := MakeBaseInput(&output.OutPoint, witnessType, signDesc, 0)
|
||||
input := input.MakeBaseInput(&output.OutPoint, witnessType, signDesc, 0)
|
||||
inputsToSweep = append(inputsToSweep, &input)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user