github.com/decred/dcrlnd@v0.7.6/input/input.go (about)

     1  package input
     2  
     3  import (
     4  	"github.com/decred/dcrd/dcrutil/v4"
     5  	"github.com/decred/dcrd/txscript/v4"
     6  	"github.com/decred/dcrd/wire"
     7  	"github.com/decred/dcrlnd/lntypes"
     8  )
     9  
    10  // Input represents an abstract UTXO which is to be spent using a sweeping
    11  // transaction. The method provided give the caller all information needed to
    12  // construct a valid input within a sweeping transaction to sweep this
    13  // lingering UTXO.
    14  type Input interface {
    15  	// Outpoint returns the reference to the output being spent, used to
    16  	// construct the corresponding transaction input.
    17  	OutPoint() *wire.OutPoint
    18  
    19  	// RequiredTxOut returns a non-nil TxOut if input commits to a certain
    20  	// transaction output. This is used in the SINGLE|ANYONECANPAY case to
    21  	// make sure any presigned input is still valid by including the
    22  	// output.
    23  	RequiredTxOut() *wire.TxOut
    24  
    25  	// RequiredLockTime returns whether this input commits to a tx locktime
    26  	// that must be used in the transaction including it.
    27  	RequiredLockTime() (uint32, bool)
    28  
    29  	// WitnessType returns an enum specifying the type of witness that must
    30  	// be generated in order to spend this output.
    31  	WitnessType() WitnessType
    32  
    33  	// SignDesc returns a reference to a spendable output's sign
    34  	// descriptor, which is used during signing to compute a valid witness
    35  	// that spends this output.
    36  	SignDesc() *SignDescriptor
    37  
    38  	// CraftInputScript returns a valid set of input scripts allowing this
    39  	// output to be spent. The returns input scripts should target the
    40  	// input at location txIndex within the passed transaction. The input
    41  	// scripts generated by this method support spending p2pkh and p2sh
    42  	// outputs.
    43  	CraftInputScript(signer Signer, txn *wire.MsgTx,
    44  		txinIdx int) (*Script, error)
    45  
    46  	// BlocksToMaturity returns the relative timelock, as a number of
    47  	// blocks, that must be built on top of the confirmation height before
    48  	// the output can be spent. For non-CSV locked inputs this is always
    49  	// zero.
    50  	BlocksToMaturity() uint32
    51  
    52  	// HeightHint returns the minimum height at which a confirmed spending
    53  	// tx can occur.
    54  	HeightHint() uint32
    55  
    56  	// UnconfParent returns information about a possibly unconfirmed parent
    57  	// tx.
    58  	UnconfParent() *TxInfo
    59  }
    60  
    61  // TxInfo describes properties of a parent tx that are relevant for CPFP.
    62  type TxInfo struct {
    63  	// Fee is the fee of the tx.
    64  	Fee dcrutil.Amount
    65  
    66  	// Size is the size of the tx.
    67  	Size int64
    68  }
    69  
    70  // SignDetails is a struct containing information needed to resign certain
    71  // inputs. It is used to re-sign 2nd level HTLC transactions that uses the
    72  // SINGLE|ANYONECANPAY sighash type, as we have a signature provided by our
    73  // peer, but we can aggregate multiple of these 2nd level transactions into a
    74  // new transaction, that needs to be signed by us.
    75  type SignDetails struct {
    76  	// SignDesc is the sign descriptor needed for us to sign the input.
    77  	SignDesc SignDescriptor
    78  
    79  	// PeerSig is the peer's signature for this input.
    80  	PeerSig Signature
    81  
    82  	// SigHashType is the sighash signed by the peer.
    83  	SigHashType txscript.SigHashType
    84  }
    85  
    86  type inputKit struct {
    87  	outpoint        wire.OutPoint
    88  	witnessType     WitnessType
    89  	signDesc        SignDescriptor
    90  	heightHint      uint32
    91  	blockToMaturity uint32
    92  	cltvExpiry      uint32
    93  
    94  	// unconfParent contains information about a potential unconfirmed
    95  	// parent transaction.
    96  	unconfParent *TxInfo
    97  }
    98  
    99  // OutPoint returns the breached output's identifier that is to be included as
   100  // a transaction input.
   101  func (i *inputKit) OutPoint() *wire.OutPoint {
   102  	return &i.outpoint
   103  }
   104  
   105  // RequiredTxOut returns a nil for the base input type.
   106  func (i *inputKit) RequiredTxOut() *wire.TxOut {
   107  	return nil
   108  }
   109  
   110  // RequiredLockTime returns whether this input commits to a tx locktime that
   111  // must be used in the transaction including it. This will be false for the
   112  // base input type since we can re-sign for any lock time.
   113  func (i *inputKit) RequiredLockTime() (uint32, bool) {
   114  	return i.cltvExpiry, i.cltvExpiry > 0
   115  }
   116  
   117  // WitnessType returns the type of witness that must be generated to spend the
   118  // breached output.
   119  func (i *inputKit) WitnessType() WitnessType {
   120  	return i.witnessType
   121  }
   122  
   123  // SignDesc returns the breached output's SignDescriptor, which is used during
   124  // signing to compute the witness.
   125  func (i *inputKit) SignDesc() *SignDescriptor {
   126  	return &i.signDesc
   127  }
   128  
   129  // HeightHint returns the minimum height at which a confirmed spending
   130  // tx can occur.
   131  func (i *inputKit) HeightHint() uint32 {
   132  	return i.heightHint
   133  }
   134  
   135  // BlocksToMaturity returns the relative timelock, as a number of blocks, that
   136  // must be built on top of the confirmation height before the output can be
   137  // spent. For non-CSV locked inputs this is always zero.
   138  func (i *inputKit) BlocksToMaturity() uint32 {
   139  	return i.blockToMaturity
   140  }
   141  
   142  // Cpfp returns information about a possibly unconfirmed parent tx.
   143  func (i *inputKit) UnconfParent() *TxInfo {
   144  	return i.unconfParent
   145  }
   146  
   147  // BaseInput contains all the information needed to sweep a basic output
   148  // (CSV/CLTV/no time lock)
   149  type BaseInput struct {
   150  	inputKit
   151  }
   152  
   153  // MakeBaseInput assembles a new BaseInput that can be used to construct a
   154  // sweep transaction.
   155  func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
   156  	signDescriptor *SignDescriptor, heightHint uint32,
   157  	unconfParent *TxInfo) BaseInput {
   158  
   159  	return BaseInput{
   160  		inputKit{
   161  			outpoint:     *outpoint,
   162  			witnessType:  witnessType,
   163  			signDesc:     *signDescriptor,
   164  			heightHint:   heightHint,
   165  			unconfParent: unconfParent,
   166  		},
   167  	}
   168  }
   169  
   170  // NewBaseInput allocates and assembles a new *BaseInput that can be used to
   171  // construct a sweep transaction.
   172  func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
   173  	signDescriptor *SignDescriptor, heightHint uint32) *BaseInput {
   174  
   175  	input := MakeBaseInput(
   176  		outpoint, witnessType, signDescriptor, heightHint, nil,
   177  	)
   178  
   179  	return &input
   180  }
   181  
   182  // NewCsvInput assembles a new csv-locked input that can be used to
   183  // construct a sweep transaction.
   184  func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType,
   185  	signDescriptor *SignDescriptor, heightHint uint32,
   186  	blockToMaturity uint32) *BaseInput {
   187  
   188  	return &BaseInput{
   189  		inputKit{
   190  			outpoint:        *outpoint,
   191  			witnessType:     witnessType,
   192  			signDesc:        *signDescriptor,
   193  			heightHint:      heightHint,
   194  			blockToMaturity: blockToMaturity,
   195  		},
   196  	}
   197  }
   198  
   199  // NewCsvInputWithCltv assembles a new csv and cltv locked input that can be
   200  // used to construct a sweep transaction.
   201  func NewCsvInputWithCltv(outpoint *wire.OutPoint, witnessType WitnessType,
   202  	signDescriptor *SignDescriptor, heightHint uint32,
   203  	csvDelay uint32, cltvExpiry uint32) *BaseInput {
   204  
   205  	return &BaseInput{
   206  		inputKit{
   207  			outpoint:        *outpoint,
   208  			witnessType:     witnessType,
   209  			signDesc:        *signDescriptor,
   210  			heightHint:      heightHint,
   211  			blockToMaturity: csvDelay,
   212  			cltvExpiry:      cltvExpiry,
   213  			unconfParent:    nil,
   214  		},
   215  	}
   216  }
   217  
   218  // CraftInputScript returns a valid set of input scripts allowing this output
   219  // to be spent. The returned input scripts should target the input at location
   220  // txIndex within the passed transaction. The input scripts generated by this
   221  // method support spending p2wkh, p2wsh, and also nested p2sh outputs.
   222  func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
   223  	txinIdx int) (*Script, error) {
   224  
   225  	witnessFunc := bi.witnessType.WitnessGenerator(signer, bi.SignDesc())
   226  
   227  	return witnessFunc(txn, txinIdx)
   228  }
   229  
   230  // HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input
   231  // is expected to reside on the commitment tx of the remote party and should
   232  // not be a second level tx output.
   233  type HtlcSucceedInput struct {
   234  	inputKit
   235  
   236  	preimage []byte
   237  }
   238  
   239  // MakeHtlcSucceedInput assembles a new redeem input that can be used to
   240  // construct a sweep transaction.
   241  func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
   242  	signDescriptor *SignDescriptor, preimage []byte, heightHint,
   243  	blocksToMaturity uint32) HtlcSucceedInput {
   244  
   245  	return HtlcSucceedInput{
   246  		inputKit: inputKit{
   247  			outpoint:        *outpoint,
   248  			witnessType:     HtlcAcceptedRemoteSuccess,
   249  			signDesc:        *signDescriptor,
   250  			heightHint:      heightHint,
   251  			blockToMaturity: blocksToMaturity,
   252  		},
   253  		preimage: preimage,
   254  	}
   255  }
   256  
   257  // CraftInputScript returns a valid set of input scripts allowing this output
   258  // to be spent. The returns input scripts should target the input at location
   259  // txIndex within the passed transaction. The input scripts generated by this
   260  // method support spending p2wkh, p2wsh, and also nested p2sh outputs.
   261  func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
   262  	txinIdx int) (*Script, error) {
   263  
   264  	desc := h.signDesc
   265  	desc.InputIndex = txinIdx
   266  
   267  	witness, err := SenderHtlcSpendRedeem(
   268  		signer, &desc, txn, h.preimage,
   269  	)
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  
   274  	return &Script{
   275  		Witness: witness,
   276  	}, nil
   277  }
   278  
   279  // HtlcsSecondLevelAnchorInput is an input type used to spend HTLC outputs
   280  // using a re-signed second level transaction, either via the timeout or success
   281  // paths.
   282  type HtlcSecondLevelAnchorInput struct {
   283  	inputKit
   284  
   285  	// SignedTx is the original second level transaction signed by the
   286  	// channel peer.
   287  	SignedTx *wire.MsgTx
   288  
   289  	// createWitness creates a witness allowing the passed transaction to
   290  	// spend the input.
   291  	createWitness func(signer Signer, txn *wire.MsgTx,
   292  		txinIdx int) (TxWitness, error)
   293  }
   294  
   295  // RequiredTxOut returns the tx out needed to be present on the sweep tx for
   296  // the spend of the input to be valid.
   297  func (i *HtlcSecondLevelAnchorInput) RequiredTxOut() *wire.TxOut {
   298  	return i.SignedTx.TxOut[0]
   299  }
   300  
   301  // RequiredLockTime returns the locktime needed for the sweep tx for the spend
   302  // of the input to be valid. For a second level HTLC timeout this will be the
   303  // CLTV expiry, for HTLC success it will be zero.
   304  func (i *HtlcSecondLevelAnchorInput) RequiredLockTime() (uint32, bool) {
   305  	return i.SignedTx.LockTime, true
   306  }
   307  
   308  // CraftInputScript returns a valid set of input scripts allowing this output
   309  // to be spent. The returns input scripts should target the input at location
   310  // txIndex within the passed transaction. The input scripts generated by this
   311  // method support spending p2wkh, p2wsh, and also nested p2sh outputs.
   312  func (i *HtlcSecondLevelAnchorInput) CraftInputScript(signer Signer,
   313  	txn *wire.MsgTx,
   314  	txinIdx int) (*Script, error) {
   315  
   316  	witness, err := i.createWitness(signer, txn, txinIdx)
   317  	if err != nil {
   318  		return nil, err
   319  	}
   320  
   321  	return &Script{
   322  		Witness: witness,
   323  	}, nil
   324  }
   325  
   326  // MakeHtlcSecondLevelTimeoutAnchorInput creates an input allowing the sweeper
   327  // to spend the HTLC output on our commit using the second level timeout
   328  // transaction.
   329  func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx,
   330  	signDetails *SignDetails, heightHint uint32) HtlcSecondLevelAnchorInput {
   331  
   332  	// Spend an HTLC output on our local commitment tx using the
   333  	// 2nd timeout transaction.
   334  	createWitness := func(signer Signer, txn *wire.MsgTx,
   335  		txinIdx int) (TxWitness, error) {
   336  
   337  		desc := signDetails.SignDesc
   338  		desc.InputIndex = txinIdx
   339  
   340  		return SenderHtlcSpendTimeout(
   341  			signDetails.PeerSig, signDetails.SigHashType, signer,
   342  			&desc, txn,
   343  		)
   344  	}
   345  
   346  	return HtlcSecondLevelAnchorInput{
   347  		inputKit: inputKit{
   348  			outpoint:    signedTx.TxIn[0].PreviousOutPoint,
   349  			witnessType: HtlcOfferedTimeoutSecondLevelInputConfirmed,
   350  			signDesc:    signDetails.SignDesc,
   351  			heightHint:  heightHint,
   352  
   353  			// CSV delay is always 1 for these inputs.
   354  			blockToMaturity: 1,
   355  		},
   356  		SignedTx:      signedTx,
   357  		createWitness: createWitness,
   358  	}
   359  }
   360  
   361  // MakeHtlcSecondLevelSuccessAnchorInput creates an input allowing the sweeper
   362  // to spend the HTLC output on our commit using the second level success
   363  // transaction.
   364  func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx,
   365  	signDetails *SignDetails, preimage lntypes.Preimage,
   366  	heightHint uint32) HtlcSecondLevelAnchorInput {
   367  
   368  	// Spend an HTLC output on our local commitment tx using the 2nd
   369  	// success transaction.
   370  	createWitness := func(signer Signer, txn *wire.MsgTx,
   371  		txinIdx int) (TxWitness, error) {
   372  
   373  		desc := signDetails.SignDesc
   374  		desc.InputIndex = txinIdx
   375  
   376  		return ReceiverHtlcSpendRedeem(
   377  			signDetails.PeerSig, signDetails.SigHashType,
   378  			preimage[:], signer, &desc, txn,
   379  		)
   380  	}
   381  
   382  	return HtlcSecondLevelAnchorInput{
   383  		inputKit: inputKit{
   384  			outpoint:    signedTx.TxIn[0].PreviousOutPoint,
   385  			witnessType: HtlcAcceptedSuccessSecondLevelInputConfirmed,
   386  			signDesc:    signDetails.SignDesc,
   387  			heightHint:  heightHint,
   388  
   389  			// CSV delay is always 1 for these inputs.
   390  			blockToMaturity: 1,
   391  		},
   392  		SignedTx:      signedTx,
   393  		createWitness: createWitness,
   394  	}
   395  }
   396  
   397  // Compile-time constraints to ensure each input struct implement the Input
   398  // interface.
   399  var _ Input = (*BaseInput)(nil)
   400  var _ Input = (*HtlcSucceedInput)(nil)
   401  var _ Input = (*HtlcSecondLevelAnchorInput)(nil)