input: refactor all inputs to use MakeBaseInput, add opts

In this commit, we refactor all the other constructors for the input to
use MakeBaseInput. We also add a new set of functional options as well.
This'll be useful later on to ensure that new options are properly
applied to all the input types.
This commit is contained in:
Olaoluwa Osuntokun 2024-06-03 23:02:40 -07:00 committed by Oliver Gugger
parent 07ee114116
commit fc02cd7b0c
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
2 changed files with 104 additions and 81 deletions

View File

@ -156,6 +156,18 @@ func (i *inputKit) UnconfParent() *TxInfo {
return i.unconfParent return i.unconfParent
} }
// inputOpts holds options for the input.
type inputOpts struct {
}
// defaultInputOpts returns a new inputOpts with default values.
func defaultInputOpts() *inputOpts {
return &inputOpts{}
}
// InputOpt is a functional option argument to the input constructor.
type InputOpt func(*inputOpts) //nolint:revive
// BaseInput contains all the information needed to sweep a basic // BaseInput contains all the information needed to sweep a basic
// output (CSV/CLTV/no time lock). // output (CSV/CLTV/no time lock).
type BaseInput struct { type BaseInput struct {
@ -166,7 +178,12 @@ type BaseInput struct {
// sweep transaction. // sweep transaction.
func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType, func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
signDescriptor *SignDescriptor, heightHint uint32, signDescriptor *SignDescriptor, heightHint uint32,
unconfParent *TxInfo) BaseInput { unconfParent *TxInfo, opts ...InputOpt) BaseInput {
opt := defaultInputOpts()
for _, optF := range opts {
optF(opt)
}
return BaseInput{ return BaseInput{
inputKit{ inputKit{
@ -182,10 +199,11 @@ func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
// NewBaseInput allocates and assembles a new *BaseInput that can be used to // NewBaseInput allocates and assembles a new *BaseInput that can be used to
// construct a sweep transaction. // construct a sweep transaction.
func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType, func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
signDescriptor *SignDescriptor, heightHint uint32) *BaseInput { signDescriptor *SignDescriptor, heightHint uint32,
opts ...InputOpt) *BaseInput {
input := MakeBaseInput( input := MakeBaseInput(
outpoint, witnessType, signDescriptor, heightHint, nil, outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
) )
return &input return &input
@ -195,36 +213,31 @@ func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
// construct a sweep transaction. // construct a sweep transaction.
func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType, func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType,
signDescriptor *SignDescriptor, heightHint uint32, signDescriptor *SignDescriptor, heightHint uint32,
blockToMaturity uint32) *BaseInput { blockToMaturity uint32, opts ...InputOpt) *BaseInput {
return &BaseInput{ input := MakeBaseInput(
inputKit{ outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
outpoint: *outpoint, )
witnessType: witnessType,
signDesc: *signDescriptor, input.blockToMaturity = blockToMaturity
heightHint: heightHint,
blockToMaturity: blockToMaturity, return &input
},
}
} }
// NewCsvInputWithCltv assembles a new csv and cltv locked input that can be // NewCsvInputWithCltv assembles a new csv and cltv locked input that can be
// used to construct a sweep transaction. // used to construct a sweep transaction.
func NewCsvInputWithCltv(outpoint *wire.OutPoint, witnessType WitnessType, func NewCsvInputWithCltv(outpoint *wire.OutPoint, witnessType WitnessType,
signDescriptor *SignDescriptor, heightHint uint32, signDescriptor *SignDescriptor, heightHint uint32,
csvDelay uint32, cltvExpiry uint32) *BaseInput { csvDelay uint32, cltvExpiry uint32, opts ...InputOpt) *BaseInput {
return &BaseInput{ input := MakeBaseInput(
inputKit{ outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
outpoint: *outpoint, )
witnessType: witnessType,
signDesc: *signDescriptor, input.blockToMaturity = csvDelay
heightHint: heightHint, input.cltvExpiry = cltvExpiry
blockToMaturity: csvDelay,
cltvExpiry: cltvExpiry, return &input
unconfParent: nil,
},
}
} }
// CraftInputScript returns a valid set of input scripts allowing this output // CraftInputScript returns a valid set of input scripts allowing this output
@ -256,16 +269,16 @@ type HtlcSucceedInput struct {
// construct a sweep transaction. // construct a sweep transaction.
func MakeHtlcSucceedInput(outpoint *wire.OutPoint, func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
signDescriptor *SignDescriptor, preimage []byte, heightHint, signDescriptor *SignDescriptor, preimage []byte, heightHint,
blocksToMaturity uint32) HtlcSucceedInput { blocksToMaturity uint32, opts ...InputOpt) HtlcSucceedInput {
input := MakeBaseInput(
outpoint, HtlcAcceptedRemoteSuccess, signDescriptor,
heightHint, nil, opts...,
)
input.blockToMaturity = blocksToMaturity
return HtlcSucceedInput{ return HtlcSucceedInput{
inputKit: inputKit{ inputKit: input.inputKit,
outpoint: *outpoint,
witnessType: HtlcAcceptedRemoteSuccess,
signDesc: *signDescriptor,
heightHint: heightHint,
blockToMaturity: blocksToMaturity,
},
preimage: preimage, preimage: preimage,
} }
} }
@ -274,16 +287,17 @@ func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
// to spend an HTLC output for a taproot channel on the remote party's // to spend an HTLC output for a taproot channel on the remote party's
// commitment transaction. // commitment transaction.
func MakeTaprootHtlcSucceedInput(op *wire.OutPoint, signDesc *SignDescriptor, func MakeTaprootHtlcSucceedInput(op *wire.OutPoint, signDesc *SignDescriptor,
preimage []byte, heightHint, blocksToMaturity uint32) HtlcSucceedInput { preimage []byte, heightHint, blocksToMaturity uint32,
opts ...InputOpt) HtlcSucceedInput {
input := MakeBaseInput(
op, TaprootHtlcAcceptedRemoteSuccess, signDesc,
heightHint, nil, opts...,
)
input.blockToMaturity = blocksToMaturity
return HtlcSucceedInput{ return HtlcSucceedInput{
inputKit: inputKit{ inputKit: input.inputKit,
outpoint: *op,
witnessType: TaprootHtlcAcceptedRemoteSuccess,
signDesc: *signDesc,
heightHint: heightHint,
blockToMaturity: blocksToMaturity,
},
preimage: preimage, preimage: preimage,
} }
} }
@ -388,7 +402,8 @@ func (i *HtlcSecondLevelAnchorInput) CraftInputScript(signer Signer,
// to spend the HTLC output on our commit using the second level timeout // to spend the HTLC output on our commit using the second level timeout
// transaction. // transaction.
func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx, func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx,
signDetails *SignDetails, heightHint uint32) HtlcSecondLevelAnchorInput { signDetails *SignDetails, heightHint uint32,
opts ...InputOpt) HtlcSecondLevelAnchorInput {
// Spend an HTLC output on our local commitment tx using the // Spend an HTLC output on our local commitment tx using the
// 2nd timeout transaction. // 2nd timeout transaction.
@ -408,16 +423,15 @@ func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx,
) )
} }
return HtlcSecondLevelAnchorInput{ input := MakeBaseInput(
inputKit: inputKit{ &signedTx.TxIn[0].PreviousOutPoint,
outpoint: signedTx.TxIn[0].PreviousOutPoint, HtlcOfferedTimeoutSecondLevelInputConfirmed,
witnessType: HtlcOfferedTimeoutSecondLevelInputConfirmed, &signDetails.SignDesc, heightHint, nil, opts...,
signDesc: signDetails.SignDesc, )
heightHint: heightHint, input.blockToMaturity = 1
// CSV delay is always 1 for these inputs. return HtlcSecondLevelAnchorInput{
blockToMaturity: 1, inputKit: input.inputKit,
},
SignedTx: signedTx, SignedTx: signedTx,
createWitness: createWitness, createWitness: createWitness,
} }
@ -429,7 +443,7 @@ func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx,
// sweep the second level HTLC aggregated with other transactions. // sweep the second level HTLC aggregated with other transactions.
func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx, func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx,
signDetails *SignDetails, signDetails *SignDetails,
heightHint uint32) HtlcSecondLevelAnchorInput { heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
createWitness := func(signer Signer, txn *wire.MsgTx, createWitness := func(signer Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, hashCache *txscript.TxSigHashes,
@ -453,16 +467,15 @@ func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx,
) )
} }
return HtlcSecondLevelAnchorInput{ input := MakeBaseInput(
inputKit: inputKit{ &signedTx.TxIn[0].PreviousOutPoint,
outpoint: signedTx.TxIn[0].PreviousOutPoint, TaprootHtlcLocalOfferedTimeout,
witnessType: TaprootHtlcLocalOfferedTimeout, &signDetails.SignDesc, heightHint, nil, opts...,
signDesc: signDetails.SignDesc, )
heightHint: heightHint, input.blockToMaturity = 1
// CSV delay is always 1 for these inputs. return HtlcSecondLevelAnchorInput{
blockToMaturity: 1, inputKit: input.inputKit,
},
SignedTx: signedTx, SignedTx: signedTx,
createWitness: createWitness, createWitness: createWitness,
} }
@ -473,7 +486,7 @@ func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx,
// transaction. // transaction.
func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx, func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx,
signDetails *SignDetails, preimage lntypes.Preimage, signDetails *SignDetails, preimage lntypes.Preimage,
heightHint uint32) HtlcSecondLevelAnchorInput { heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
// Spend an HTLC output on our local commitment tx using the 2nd // Spend an HTLC output on our local commitment tx using the 2nd
// success transaction. // success transaction.
@ -492,18 +505,16 @@ func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx,
preimage[:], signer, &desc, txn, preimage[:], signer, &desc, txn,
) )
} }
input := MakeBaseInput(
&signedTx.TxIn[0].PreviousOutPoint,
HtlcAcceptedSuccessSecondLevelInputConfirmed,
&signDetails.SignDesc, heightHint, nil, opts...,
)
input.blockToMaturity = 1
return HtlcSecondLevelAnchorInput{ return HtlcSecondLevelAnchorInput{
inputKit: inputKit{
outpoint: signedTx.TxIn[0].PreviousOutPoint,
witnessType: HtlcAcceptedSuccessSecondLevelInputConfirmed,
signDesc: signDetails.SignDesc,
heightHint: heightHint,
// CSV delay is always 1 for these inputs.
blockToMaturity: 1,
},
SignedTx: signedTx, SignedTx: signedTx,
inputKit: input.inputKit,
createWitness: createWitness, createWitness: createWitness,
} }
} }
@ -513,7 +524,7 @@ func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx,
// commitment transaction. // commitment transaction.
func MakeHtlcSecondLevelSuccessTaprootInput(signedTx *wire.MsgTx, func MakeHtlcSecondLevelSuccessTaprootInput(signedTx *wire.MsgTx,
signDetails *SignDetails, preimage lntypes.Preimage, signDetails *SignDetails, preimage lntypes.Preimage,
heightHint uint32) HtlcSecondLevelAnchorInput { heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
createWitness := func(signer Signer, txn *wire.MsgTx, createWitness := func(signer Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, hashCache *txscript.TxSigHashes,
@ -537,16 +548,15 @@ func MakeHtlcSecondLevelSuccessTaprootInput(signedTx *wire.MsgTx,
) )
} }
return HtlcSecondLevelAnchorInput{ input := MakeBaseInput(
inputKit: inputKit{ &signedTx.TxIn[0].PreviousOutPoint,
outpoint: signedTx.TxIn[0].PreviousOutPoint, TaprootHtlcAcceptedLocalSuccess,
witnessType: TaprootHtlcAcceptedLocalSuccess, &signDetails.SignDesc, heightHint, nil, opts...,
signDesc: signDetails.SignDesc, )
heightHint: heightHint, input.blockToMaturity = 1
// CSV delay is always 1 for these inputs. return HtlcSecondLevelAnchorInput{
blockToMaturity: 1, inputKit: input.inputKit,
},
SignedTx: signedTx, SignedTx: signedTx,
createWitness: createWitness, createWitness: createWitness,
} }

View File

@ -8,8 +8,10 @@ import (
"github.com/btcsuite/btcd/btcec/v2/schnorr/musig2" "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/tlv"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
) )
@ -127,6 +129,17 @@ func (m *MockInput) UnconfParent() *TxInfo {
return info.(*TxInfo) return info.(*TxInfo)
} }
func (m *MockInput) ResolutionBlob() fn.Option[tlv.Blob] {
args := m.Called()
info := args.Get(0)
if info == nil {
return fn.None[tlv.Blob]()
}
return info.(fn.Option[tlv.Blob])
}
// MockWitnessType implements the `WitnessType` interface and is used by other // MockWitnessType implements the `WitnessType` interface and is used by other
// packages for mock testing. // packages for mock testing.
type MockWitnessType struct { type MockWitnessType struct {