watchtower: introduce CommitmentType

In this commit a new enum, CommitmentType, is introduced and initially
there are 3 CommitmentTypes: Legacy, LegacyTweakless and Anchor.

Then, various methods are added to `CommitmentType`. This allows us to
remove a bunch of "if-else" chains from the `wtclient` and `lookout`
code. This will also make things easier to extend when a new commitment
type (like Taproot) is added.
This commit is contained in:
Elle Mouton 2023-05-30 17:13:11 +02:00
parent 4d8fa349ca
commit 204ca6cb0f
No known key found for this signature in database
GPG Key ID: D7D916376026F177
6 changed files with 305 additions and 161 deletions

View File

@ -0,0 +1,174 @@
package blob
import (
"fmt"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
)
// CommitmentType characterises the various properties of the breach commitment
// transaction.
type CommitmentType uint8
const (
// LegacyCommitment represents a legacy commitment transaction where
// anchor outputs are not yet used and so the to_remote output is just
// a regular but tweaked P2WKH.
LegacyCommitment CommitmentType = iota
// LegacyTweaklessCommitment is similar to the LegacyCommitment with the
// added detail of the to_remote output not being tweaked.
LegacyTweaklessCommitment
// AnchorCommitment represents the commitment transaction of an
// anchor channel. The key differences are that the to_remote is
// encumbered by a 1 block CSV and so is thus a P2WSH output.
AnchorCommitment
)
// ToLocalInput constructs the input that will be used to spend the to_local
// output.
func (c CommitmentType) ToLocalInput(info *lnwallet.BreachRetribution) (
input.Input, error) {
witnessType, err := c.ToLocalWitnessType()
if err != nil {
return nil, err
}
return input.NewBaseInput(
&info.RemoteOutpoint, witnessType, info.RemoteOutputSignDesc, 0,
), nil
}
// ToRemoteInput constructs the input that will be used to spend the to_remote
// output.
func (c CommitmentType) ToRemoteInput(info *lnwallet.BreachRetribution) (
input.Input, error) {
witnessType, err := c.ToRemoteWitnessType()
if err != nil {
return nil, err
}
switch c {
case LegacyCommitment, LegacyTweaklessCommitment:
return input.NewBaseInput(
&info.LocalOutpoint, witnessType,
info.LocalOutputSignDesc, 0,
), nil
case AnchorCommitment:
// Anchor channels have a CSV-encumbered to-remote output. We'll
// construct a CSV input and assign the proper CSV delay of 1.
return input.NewCsvInput(
&info.LocalOutpoint, witnessType,
info.LocalOutputSignDesc, 0, 1,
), nil
default:
return nil, fmt.Errorf("unknown commitment type: %v", c)
}
}
// ToLocalWitnessType is the input type of the to_local output.
func (c CommitmentType) ToLocalWitnessType() (input.WitnessType, error) {
switch c {
case LegacyTweaklessCommitment, LegacyCommitment, AnchorCommitment:
return input.CommitmentRevoke, nil
default:
return nil, fmt.Errorf("unknown commitment type: %v", c)
}
}
// ToRemoteWitnessType is the input type of the to_remote output.
func (c CommitmentType) ToRemoteWitnessType() (input.WitnessType, error) {
switch c {
case LegacyTweaklessCommitment:
return input.CommitSpendNoDelayTweakless, nil
case LegacyCommitment:
return input.CommitmentNoDelay, nil
case AnchorCommitment:
return input.CommitmentToRemoteConfirmed, nil
default:
return nil, fmt.Errorf("unknown commitment type: %v", c)
}
}
// ToRemoteWitnessSize is the size of the witness that will be required to spend
// the to_remote output.
func (c CommitmentType) ToRemoteWitnessSize() (int, error) {
switch c {
// Legacy channels (both tweaked and non-tweaked) spend from P2WKH
// output.
case LegacyTweaklessCommitment, LegacyCommitment:
return input.P2WKHWitnessSize, nil
// Anchor channels spend a to-remote confirmed P2WSH output.
case AnchorCommitment:
return input.ToRemoteConfirmedWitnessSize, nil
default:
return 0, fmt.Errorf("unknown commitment type: %v", c)
}
}
// ToLocalWitnessSize is the size of the witness that will be required to spend
// the to_local output.
func (c CommitmentType) ToLocalWitnessSize() (int, error) {
switch c {
// An older ToLocalPenaltyWitnessSize constant used to underestimate the
// size by one byte. The difference in weight can cause different output
// values on the sweep transaction, so we mimic the original bug and
// create signatures using the original weight estimate.
case LegacyTweaklessCommitment, LegacyCommitment:
return input.ToLocalPenaltyWitnessSize - 1, nil
case AnchorCommitment:
return input.ToLocalPenaltyWitnessSize, nil
default:
return 0, fmt.Errorf("unknown commitment type: %v", c)
}
}
// ParseRawSig parses a wire.TxWitness and creates an lnwire.Sig.
func (c CommitmentType) ParseRawSig(witness wire.TxWitness) (lnwire.Sig,
error) {
switch c {
case LegacyCommitment, LegacyTweaklessCommitment, AnchorCommitment:
// Check that the witness has at least one item.
if len(witness) < 1 {
return lnwire.Sig{}, fmt.Errorf("the witness should " +
"have at least one element")
}
// Check that the first witness element is non-nil. This is to
// ensure that the witness length check below does not panic.
if witness[0] == nil {
return lnwire.Sig{}, fmt.Errorf("the first witness " +
"element should not be nil")
}
// Parse the DER-encoded signature from the first position of
// the resulting witness. We trim an extra byte to remove the
// sighash flag.
rawSignature := witness[0][:len(witness[0])-1]
// Re-encode the DER signature into a fixed-size 64 byte
// signature.
return lnwire.NewSigFromECDSARawSignature(rawSignature)
default:
return lnwire.Sig{}, fmt.Errorf("unknown commitment type: %v",
c)
}
}

View File

@ -3,6 +3,8 @@ package blob
import ( import (
"fmt" "fmt"
"strings" "strings"
"github.com/lightningnetwork/lnd/channeldb"
) )
// Flag represents a specify option that can be present in a Type. // Flag represents a specify option that can be present in a Type.
@ -81,6 +83,27 @@ func (t Type) Identifier() (string, error) {
} }
} }
// CommitmentType returns the appropriate CommitmentType for the given blob Type
// and channel type.
func (t Type) CommitmentType(chanType *channeldb.ChannelType) (CommitmentType,
error) {
switch {
case t.Has(FlagAnchorChannel):
return AnchorCommitment, nil
case t.Has(FlagCommitOutputs):
if chanType != nil && chanType.IsTweakless() {
return LegacyTweaklessCommitment, nil
}
return LegacyCommitment, nil
default:
return 0, ErrUnknownBlobType
}
}
// Has returns true if the Type has the passed flag enabled. // Has returns true if the Type has the passed flag enabled.
func (t Type) Has(flag Flag) bool { func (t Type) Has(flag Flag) bool {
return Flag(t)&flag == flag return Flag(t)&flag == flag

View File

@ -264,6 +264,11 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) {
weightEstimate input.TxWeightEstimator weightEstimate input.TxWeightEstimator
) )
commitmentType, err := p.SessionInfo.Policy.BlobType.CommitmentType(nil)
if err != nil {
return nil, err
}
// Add the sweep address's contribution, depending on whether it is a // Add the sweep address's contribution, depending on whether it is a
// p2wkh or p2wsh output. // p2wkh or p2wsh output.
switch len(p.JusticeKit.SweepAddress) { switch len(p.JusticeKit.SweepAddress) {
@ -290,16 +295,13 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) {
return nil, err return nil, err
} }
// An older ToLocalPenaltyWitnessSize constant used to underestimate the // Get the weight for the to-local witness and add that to the
// size by one byte. The diferrence in weight can cause different output // estimator.
// values on the sweep transaction, so we mimic the original bug to toLocalWitnessSize, err := commitmentType.ToLocalWitnessSize()
// avoid invalidating signatures by older clients. For anchor channels if err != nil {
// we correct this and use the correct witness size. return nil, err
if p.JusticeKit.BlobType.IsAnchorChannel() {
weightEstimate.AddWitnessInput(input.ToLocalPenaltyWitnessSize)
} else {
weightEstimate.AddWitnessInput(input.ToLocalPenaltyWitnessSize - 1)
} }
weightEstimate.AddWitnessInput(toLocalWitnessSize)
sweepInputs = append(sweepInputs, toLocalInput) sweepInputs = append(sweepInputs, toLocalInput)
@ -319,11 +321,14 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) {
log.Debugf("Found to remote witness output=%#v, stack=%v", log.Debugf("Found to remote witness output=%#v, stack=%v",
toRemoteInput.txOut, toRemoteInput.witness) toRemoteInput.txOut, toRemoteInput.witness)
if p.JusticeKit.BlobType.IsAnchorChannel() { // Get the weight for the to-remote witness and add that to the
weightEstimate.AddWitnessInput(input.ToRemoteConfirmedWitnessSize) // estimator.
} else { toRemoteWitnessSize, err := commitmentType.ToRemoteWitnessSize()
weightEstimate.AddWitnessInput(input.P2WKHWitnessSize) if err != nil {
return nil, err
} }
weightEstimate.AddWitnessInput(toRemoteWitnessSize)
} }
// TODO(conner): sweep htlc outputs // TODO(conner): sweep htlc outputs

View File

@ -92,15 +92,13 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
) )
// Parse the key pairs for all keys used in the test. // Parse the key pairs for all keys used in the test.
revSK, revPK := btcec.PrivKeyFromBytes( revSK, revPK := btcec.PrivKeyFromBytes(revPrivBytes)
revPrivBytes, _, toLocalPK := btcec.PrivKeyFromBytes(toLocalPrivBytes)
) toRemoteSK, toRemotePK := btcec.PrivKeyFromBytes(toRemotePrivBytes)
_, toLocalPK := btcec.PrivKeyFromBytes(
toLocalPrivBytes, // Get the commitment type.
) commitType, err := blobType.CommitmentType(nil)
toRemoteSK, toRemotePK := btcec.PrivKeyFromBytes( require.NoError(t, err)
toRemotePrivBytes,
)
// Create the signer, and add the revocation and to-remote privkeys. // Create the signer, and add the revocation and to-remote privkeys.
signer := wtmock.NewMockSigner() signer := wtmock.NewMockSigner()
@ -113,11 +111,11 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
toLocalScript, err := input.CommitScriptToSelf( toLocalScript, err := input.CommitScriptToSelf(
csvDelay, toLocalPK, revPK, csvDelay, toLocalPK, revPK,
) )
require.Nil(t, err) require.NoError(t, err)
// Compute the to-local witness script hash. // Compute the to-local witness script hash.
toLocalScriptHash, err := input.WitnessScriptHash(toLocalScript) toLocalScriptHash, err := input.WitnessScriptHash(toLocalScript)
require.Nil(t, err) require.NoError(t, err)
// Compute the to-remote redeem script, witness script hash, and // Compute the to-remote redeem script, witness script hash, and
// sequence numbers. // sequence numbers.
@ -147,12 +145,12 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
toRemoteRedeemScript, err = input.CommitScriptToRemoteConfirmed( toRemoteRedeemScript, err = input.CommitScriptToRemoteConfirmed(
toRemotePK, toRemotePK,
) )
require.Nil(t, err) require.NoError(t, err)
toRemoteScriptHash, err = input.WitnessScriptHash( toRemoteScriptHash, err = input.WitnessScriptHash(
toRemoteRedeemScript, toRemoteRedeemScript,
) )
require.Nil(t, err) require.NoError(t, err)
// As it should be. // As it should be.
toRemoteSigningScript = toRemoteRedeemScript toRemoteSigningScript = toRemoteRedeemScript
@ -161,7 +159,7 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
toRemoteScriptHash, err = input.CommitScriptUnencumbered( toRemoteScriptHash, err = input.CommitScriptUnencumbered(
toRemotePK, toRemotePK,
) )
require.Nil(t, err) require.NoError(t, err)
// NOTE: This is the _pkscript_. // NOTE: This is the _pkscript_.
toRemoteSigningScript = toRemoteScriptHash toRemoteSigningScript = toRemoteScriptHash
@ -188,26 +186,24 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
// Compute the weight estimate for our justice transaction. // Compute the weight estimate for our justice transaction.
var weightEstimate input.TxWeightEstimator var weightEstimate input.TxWeightEstimator
// An older ToLocalPenaltyWitnessSize constant used to underestimate the // Add the local witness size to the weight estimator.
// size by one byte. The diferrence in weight can cause different output toLocalWitnessSize, err := commitType.ToLocalWitnessSize()
// values on the sweep transaction, so we mimic the original bug and require.NoError(t, err)
// create signatures using the original weight estimate. For anchor weightEstimate.AddWitnessInput(toLocalWitnessSize)
// channels we fix this and use the correct witness size.
if isAnchorChannel {
weightEstimate.AddWitnessInput(input.ToLocalPenaltyWitnessSize)
} else {
weightEstimate.AddWitnessInput(input.ToLocalPenaltyWitnessSize - 1)
}
if isAnchorChannel { // Add the remote witness size to the weight estimator.
weightEstimate.AddWitnessInput(input.ToRemoteConfirmedWitnessSize) toRemoteWitnessSize, err := commitType.ToRemoteWitnessSize()
} else { require.NoError(t, err)
weightEstimate.AddWitnessInput(input.P2WKHWitnessSize) weightEstimate.AddWitnessInput(toRemoteWitnessSize)
}
// Add the sweep output to the weight estimator.
weightEstimate.AddP2WKHOutput() weightEstimate.AddP2WKHOutput()
// Add the reward output to the weight estimator.
if blobType.Has(blob.FlagReward) { if blobType.Has(blob.FlagReward) {
weightEstimate.AddP2WKHOutput() weightEstimate.AddP2WKHOutput()
} }
txWeight := weightEstimate.Weight() txWeight := weightEstimate.Weight()
// Create a session info so that simulate agreement of the sweep // Create a session info so that simulate agreement of the sweep
@ -263,7 +259,7 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
totalAmount, int64(txWeight), justiceKit.SweepAddress, totalAmount, int64(txWeight), justiceKit.SweepAddress,
sessionInfo.RewardAddress, sessionInfo.RewardAddress,
) )
require.Nil(t, err) require.NoError(t, err)
// Attach the txouts and BIP69 sort the resulting transaction. // Attach the txouts and BIP69 sort the resulting transaction.
justiceTxn.TxOut = outputs justiceTxn.TxOut = outputs

View File

@ -12,7 +12,6 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/watchtower/blob" "github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtdb" "github.com/lightningnetwork/lnd/watchtower/wtdb"
) )
@ -39,6 +38,7 @@ import (
type backupTask struct { type backupTask struct {
id wtdb.BackupID id wtdb.BackupID
breachInfo *lnwallet.BreachRetribution breachInfo *lnwallet.BreachRetribution
commitmentType blob.CommitmentType
// state-dependent variables // state-dependent variables
@ -127,6 +127,11 @@ func (t *backupTask) bindSession(session *wtdb.ClientSessionBody,
return err return err
} }
commitType, err := session.Policy.BlobType.CommitmentType(&chanType)
if err != nil {
return err
}
// Parse the non-dust outputs from the breach transaction, // Parse the non-dust outputs from the breach transaction,
// simultaneously computing the total amount contained in the inputs // simultaneously computing the total amount contained in the inputs
// present. We can't compute the exact output values at this time // present. We can't compute the exact output values at this time
@ -147,48 +152,23 @@ func (t *backupTask) bindSession(session *wtdb.ClientSessionBody,
// to that output as local, though relative to their commitment, it is // to that output as local, though relative to their commitment, it is
// paying to-the-remote party (which is us). // paying to-the-remote party (which is us).
if breachInfo.RemoteOutputSignDesc != nil { if breachInfo.RemoteOutputSignDesc != nil {
toLocalInput = input.NewBaseInput( toLocalInput, err = commitType.ToLocalInput(breachInfo)
&breachInfo.RemoteOutpoint, if err != nil {
input.CommitmentRevoke, return err
breachInfo.RemoteOutputSignDesc, }
0,
)
totalAmt += breachInfo.RemoteOutputSignDesc.Output.Value totalAmt += breachInfo.RemoteOutputSignDesc.Output.Value
} }
if breachInfo.LocalOutputSignDesc != nil { if breachInfo.LocalOutputSignDesc != nil {
var witnessType input.WitnessType toRemoteInput, err = commitType.ToRemoteInput(breachInfo)
switch { if err != nil {
case chanType.HasAnchors(): return err
witnessType = input.CommitmentToRemoteConfirmed
case chanType.IsTweakless():
witnessType = input.CommitSpendNoDelayTweakless
default:
witnessType = input.CommitmentNoDelay
}
// Anchor channels have a CSV-encumbered to-remote output. We'll
// construct a CSV input in that case and assign the proper CSV
// delay of 1, otherwise we fallback to the a regular P2WKH
// to-remote output for tweaked or tweakless channels.
if chanType.HasAnchors() {
toRemoteInput = input.NewCsvInput(
&breachInfo.LocalOutpoint,
witnessType,
breachInfo.LocalOutputSignDesc,
0, 1,
)
} else {
toRemoteInput = input.NewBaseInput(
&breachInfo.LocalOutpoint,
witnessType,
breachInfo.LocalOutputSignDesc,
0,
)
} }
totalAmt += breachInfo.LocalOutputSignDesc.Output.Value totalAmt += breachInfo.LocalOutputSignDesc.Output.Value
} }
t.commitmentType = commitType
t.breachInfo = breachInfo t.breachInfo = breachInfo
t.toLocalInput = toLocalInput t.toLocalInput = toLocalInput
t.toRemoteInput = toRemoteInput t.toRemoteInput = toRemoteInput
@ -202,34 +182,20 @@ func (t *backupTask) bindSession(session *wtdb.ClientSessionBody,
// Next, add the contribution from the inputs that are present on this // Next, add the contribution from the inputs that are present on this
// breach transaction. // breach transaction.
if t.toLocalInput != nil { if t.toLocalInput != nil {
// An older ToLocalPenaltyWitnessSize constant used to toLocalWitnessSize, err := commitType.ToLocalWitnessSize()
// underestimate the size by one byte. The diferrence in weight if err != nil {
// can cause different output values on the sweep transaction, return err
// so we mimic the original bug and create signatures using the
// original weight estimate. For anchor channels we'll go ahead
// an use the correct penalty witness when signing our justice
// transactions.
if chanType.HasAnchors() {
weightEstimate.AddWitnessInput(
input.ToLocalPenaltyWitnessSize,
)
} else {
weightEstimate.AddWitnessInput(
input.ToLocalPenaltyWitnessSize - 1,
)
} }
weightEstimate.AddWitnessInput(toLocalWitnessSize)
} }
if t.toRemoteInput != nil { if t.toRemoteInput != nil {
// Legacy channels (both tweaked and non-tweaked) spend from toRemoteWitnessSize, err := commitType.ToRemoteWitnessSize()
// P2WKH output. Anchor channels spend a to-remote confirmed if err != nil {
// P2WSH output. return err
if chanType.HasAnchors() {
weightEstimate.AddWitnessInput(
input.ToRemoteConfirmedWitnessSize,
)
} else {
weightEstimate.AddWitnessInput(input.P2WKHWitnessSize)
} }
weightEstimate.AddWitnessInput(toRemoteWitnessSize)
} }
// All justice transactions will either use segwit v0 (p2wkh + p2wsh) // All justice transactions will either use segwit v0 (p2wkh + p2wsh)
@ -349,6 +315,7 @@ func (t *backupTask) craftSessionPayload(
// Now, iterate through the list of inputs that were initially added to // Now, iterate through the list of inputs that were initially added to
// the transaction and store the computed witness within the justice // the transaction and store the computed witness within the justice
// kit. // kit.
commitType := t.commitmentType
for _, inp := range inputs { for _, inp := range inputs {
// Lookup the input's new post-sort position. // Lookup the input's new post-sort position.
i := inputIndex[*inp.OutPoint()] i := inputIndex[*inp.OutPoint()]
@ -361,17 +328,17 @@ func (t *backupTask) craftSessionPayload(
return hint, nil, err return hint, nil, err
} }
// Parse the DER-encoded signature from the first position of signature, err := commitType.ParseRawSig(inputScript.Witness)
// the resulting witness. We trim an extra byte to remove the if err != nil {
// sighash flag. return hint, nil, err
witness := inputScript.Witness }
rawSignature := witness[0][:len(witness[0])-1]
// Re-encode the DER signature into a fixed-size 64 byte toLocalWitnessType, err := commitType.ToLocalWitnessType()
// signature. if err != nil {
signature, err := lnwire.NewSigFromECDSARawSignature( return hint, nil, err
rawSignature, }
)
toRemoteWitnessType, err := commitType.ToRemoteWitnessType()
if err != nil { if err != nil {
return hint, nil, err return hint, nil, err
} }
@ -380,14 +347,9 @@ func (t *backupTask) craftSessionPayload(
// using the input's witness type to select the appropriate // using the input's witness type to select the appropriate
// field // field
switch inp.WitnessType() { switch inp.WitnessType() {
case input.CommitmentRevoke: case toLocalWitnessType:
justiceKit.CommitToLocalSig = signature justiceKit.CommitToLocalSig = signature
case toRemoteWitnessType:
case input.CommitSpendNoDelayTweakless:
fallthrough
case input.CommitmentNoDelay:
fallthrough
case input.CommitmentToRemoteConfirmed:
justiceKit.CommitToRemoteSig = signature justiceKit.CommitToRemoteSig = signature
default: default:
return hint, nil, fmt.Errorf("invalid witness type: %v", return hint, nil, fmt.Errorf("invalid witness type: %v",

View File

@ -72,6 +72,7 @@ type backupTaskTest struct {
// corresponding BreachInfo, as well as setting the wtpolicy.Policy of the given // corresponding BreachInfo, as well as setting the wtpolicy.Policy of the given
// session. // session.
func genTaskTest( func genTaskTest(
t *testing.T,
name string, name string,
stateNum uint64, stateNum uint64,
toLocalAmt int64, toLocalAmt int64,
@ -91,15 +92,12 @@ func genTaskTest(
} }
// Parse the key pairs for all keys used in the test. // Parse the key pairs for all keys used in the test.
revSK, revPK := btcec.PrivKeyFromBytes( revSK, revPK := btcec.PrivKeyFromBytes(revPrivBytes)
revPrivBytes, _, toLocalPK := btcec.PrivKeyFromBytes(toLocalPrivBytes)
) toRemoteSK, toRemotePK := btcec.PrivKeyFromBytes(toRemotePrivBytes)
_, toLocalPK := btcec.PrivKeyFromBytes(
toLocalPrivBytes, commitType, err := blobType.CommitmentType(&chanType)
) require.NoError(t, err)
toRemoteSK, toRemotePK := btcec.PrivKeyFromBytes(
toRemotePrivBytes,
)
// Create the signer, and add the revocation and to-remote privkeys. // Create the signer, and add the revocation and to-remote privkeys.
signer := wtmock.NewMockSigner() signer := wtmock.NewMockSigner()
@ -174,12 +172,9 @@ func genTaskTest(
Hash: txid, Hash: txid,
Index: index, Index: index,
} }
toLocalInput = input.NewBaseInput( toLocalInput, err = commitType.ToLocalInput(breachInfo)
&breachInfo.RemoteOutpoint, require.NoError(t, err)
input.CommitmentRevoke,
breachInfo.RemoteOutputSignDesc,
0,
)
index++ index++
} }
if toRemoteAmt > 0 { if toRemoteAmt > 0 {
@ -188,31 +183,8 @@ func genTaskTest(
Index: index, Index: index,
} }
var witnessType input.WitnessType toRemoteInput, err = commitType.ToRemoteInput(breachInfo)
switch { require.NoError(t, err)
case chanType.HasAnchors():
witnessType = input.CommitmentToRemoteConfirmed
case chanType.IsTweakless():
witnessType = input.CommitSpendNoDelayTweakless
default:
witnessType = input.CommitmentNoDelay
}
if chanType.HasAnchors() {
toRemoteInput = input.NewCsvInput(
&breachInfo.LocalOutpoint,
witnessType,
breachInfo.LocalOutputSignDesc,
0, 1,
)
} else {
toRemoteInput = input.NewBaseInput(
&breachInfo.LocalOutpoint,
witnessType,
breachInfo.LocalOutputSignDesc,
0,
)
}
} }
return backupTaskTest{ return backupTaskTest{
@ -312,6 +284,7 @@ func TestBackupTask(t *testing.T) {
backupTaskTests = append(backupTaskTests, []backupTaskTest{ backupTaskTests = append(backupTaskTests, []backupTaskTest{
genTaskTest( genTaskTest(
t,
"commit no-reward, both outputs", "commit no-reward, both outputs",
100, // stateNum 100, // stateNum
200000, // toLocalAmt 200000, // toLocalAmt
@ -325,6 +298,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit no-reward, to-local output only", "commit no-reward, to-local output only",
1000, // stateNum 1000, // stateNum
200000, // toLocalAmt 200000, // toLocalAmt
@ -338,6 +312,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit no-reward, to-remote output only", "commit no-reward, to-remote output only",
1, // stateNum 1, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -351,6 +326,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit no-reward, to-remote output only, creates dust", "commit no-reward, to-remote output only, creates dust",
1, // stateNum 1, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -364,6 +340,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit no-reward, no outputs, fee rate exceeds inputs", "commit no-reward, no outputs, fee rate exceeds inputs",
300, // stateNum 300, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -377,6 +354,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit no-reward, no outputs, fee rate of 0 creates dust", "commit no-reward, no outputs, fee rate of 0 creates dust",
300, // stateNum 300, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -390,6 +368,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit reward, both outputs", "commit reward, both outputs",
100, // stateNum 100, // stateNum
200000, // toLocalAmt 200000, // toLocalAmt
@ -403,6 +382,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit reward, to-local output only", "commit reward, to-local output only",
1000, // stateNum 1000, // stateNum
200000, // toLocalAmt 200000, // toLocalAmt
@ -416,6 +396,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit reward, to-remote output only", "commit reward, to-remote output only",
1, // stateNum 1, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -429,6 +410,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit reward, to-remote output only, creates dust", "commit reward, to-remote output only, creates dust",
1, // stateNum 1, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -442,6 +424,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit reward, no outputs, fee rate exceeds inputs", "commit reward, no outputs, fee rate exceeds inputs",
300, // stateNum 300, // stateNum
0, // toLocalAmt 0, // toLocalAmt
@ -455,6 +438,7 @@ func TestBackupTask(t *testing.T) {
chanType, chanType,
), ),
genTaskTest( genTaskTest(
t,
"commit reward, no outputs, fee rate of 0 creates dust", "commit reward, no outputs, fee rate of 0 creates dust",
300, // stateNum 300, // stateNum
0, // toLocalAmt 0, // toLocalAmt