input.go
1 package input 2 3 import ( 4 "fmt" 5 6 "github.com/btcsuite/btcd/btcutil" 7 "github.com/btcsuite/btcd/txscript" 8 "github.com/btcsuite/btcd/wire" 9 "github.com/lightningnetwork/lnd/fn/v2" 10 "github.com/lightningnetwork/lnd/lntypes" 11 "github.com/lightningnetwork/lnd/tlv" 12 ) 13 14 // EmptyOutPoint is a zeroed outpoint. 15 var EmptyOutPoint wire.OutPoint 16 17 // Input represents an abstract UTXO which is to be spent using a sweeping 18 // transaction. The method provided give the caller all information needed to 19 // construct a valid input within a sweeping transaction to sweep this 20 // lingering UTXO. 21 type Input interface { 22 // OutPoint returns the reference to the output being spent, used to 23 // construct the corresponding transaction input. 24 OutPoint() wire.OutPoint 25 26 // RequiredTxOut returns a non-nil TxOut if input commits to a certain 27 // transaction output. This is used in the SINGLE|ANYONECANPAY case to 28 // make sure any presigned input is still valid by including the 29 // output. 30 RequiredTxOut() *wire.TxOut 31 32 // RequiredLockTime returns whether this input commits to a tx locktime 33 // that must be used in the transaction including it. 34 RequiredLockTime() (uint32, bool) 35 36 // WitnessType returns an enum specifying the type of witness that must 37 // be generated in order to spend this output. 38 WitnessType() WitnessType 39 40 // SignDesc returns a reference to a spendable output's sign 41 // descriptor, which is used during signing to compute a valid witness 42 // that spends this output. 43 SignDesc() *SignDescriptor 44 45 // CraftInputScript returns a valid set of input scripts allowing this 46 // output to be spent. The returns input scripts should target the 47 // input at location txIndex within the passed transaction. The input 48 // scripts generated by this method support spending p2wkh, p2wsh, and 49 // also nested p2sh outputs. 50 CraftInputScript(signer Signer, txn *wire.MsgTx, 51 hashCache *txscript.TxSigHashes, 52 prevOutputFetcher txscript.PrevOutputFetcher, 53 txinIdx int) (*Script, error) 54 55 // BlocksToMaturity returns the relative timelock, as a number of 56 // blocks, that must be built on top of the confirmation height before 57 // the output can be spent. For non-CSV locked inputs this is always 58 // zero. 59 BlocksToMaturity() uint32 60 61 // HeightHint returns the minimum height at which a confirmed spending 62 // tx can occur. 63 HeightHint() uint32 64 65 // UnconfParent returns information about a possibly unconfirmed parent 66 // tx. 67 UnconfParent() *TxInfo 68 69 // ResolutionBlob returns a special opaque blob to be used to 70 // sweep/resolve this input. 71 ResolutionBlob() fn.Option[tlv.Blob] 72 73 // Preimage returns the preimage for the input if it is an HTLC input. 74 Preimage() fn.Option[lntypes.Preimage] 75 } 76 77 // TxInfo describes properties of a parent tx that are relevant for CPFP. 78 type TxInfo struct { 79 // Fee is the fee of the tx. 80 Fee btcutil.Amount 81 82 // Weight is the weight of the tx. 83 Weight lntypes.WeightUnit 84 } 85 86 // String returns a human readable version of the tx info. 87 func (t *TxInfo) String() string { 88 return fmt.Sprintf("fee=%v, weight=%v", t.Fee, t.Weight) 89 } 90 91 // SignDetails is a struct containing information needed to resign certain 92 // inputs. It is used to re-sign 2nd level HTLC transactions that uses the 93 // SINGLE|ANYONECANPAY sighash type, as we have a signature provided by our 94 // peer, but we can aggregate multiple of these 2nd level transactions into a 95 // new transaction, that needs to be signed by us. 96 type SignDetails struct { 97 // SignDesc is the sign descriptor needed for us to sign the input. 98 SignDesc SignDescriptor 99 100 // PeerSig is the peer's signature for this input. 101 PeerSig Signature 102 103 // SigHashType is the sighash signed by the peer. 104 SigHashType txscript.SigHashType 105 } 106 107 type inputKit struct { 108 outpoint wire.OutPoint 109 witnessType WitnessType 110 signDesc SignDescriptor 111 heightHint uint32 112 blockToMaturity uint32 113 cltvExpiry uint32 114 115 // unconfParent contains information about a potential unconfirmed 116 // parent transaction. 117 unconfParent *TxInfo 118 119 // resolutionBlob is an optional blob that can be used to resolve an 120 // input. 121 resolutionBlob fn.Option[tlv.Blob] 122 } 123 124 // OutPoint returns the breached output's identifier that is to be included as 125 // a transaction input. 126 func (i *inputKit) OutPoint() wire.OutPoint { 127 return i.outpoint 128 } 129 130 // RequiredTxOut returns a nil for the base input type. 131 func (i *inputKit) RequiredTxOut() *wire.TxOut { 132 return nil 133 } 134 135 // RequiredLockTime returns whether this input commits to a tx locktime that 136 // must be used in the transaction including it. This will be false for the 137 // base input type since we can re-sign for any lock time. 138 func (i *inputKit) RequiredLockTime() (uint32, bool) { 139 return i.cltvExpiry, i.cltvExpiry > 0 140 } 141 142 // WitnessType returns the type of witness that must be generated to spend the 143 // breached output. 144 func (i *inputKit) WitnessType() WitnessType { 145 return i.witnessType 146 } 147 148 // SignDesc returns the breached output's SignDescriptor, which is used during 149 // signing to compute the witness. 150 func (i *inputKit) SignDesc() *SignDescriptor { 151 return &i.signDesc 152 } 153 154 // HeightHint returns the minimum height at which a confirmed spending 155 // tx can occur. 156 func (i *inputKit) HeightHint() uint32 { 157 return i.heightHint 158 } 159 160 // BlocksToMaturity returns the relative timelock, as a number of blocks, that 161 // must be built on top of the confirmation height before the output can be 162 // spent. For non-CSV locked inputs this is always zero. 163 func (i *inputKit) BlocksToMaturity() uint32 { 164 return i.blockToMaturity 165 } 166 167 // Cpfp returns information about a possibly unconfirmed parent tx. 168 func (i *inputKit) UnconfParent() *TxInfo { 169 return i.unconfParent 170 } 171 172 // ResolutionBlob returns a special opaque blob to be used to sweep/resolve 173 // this input. 174 func (i *inputKit) ResolutionBlob() fn.Option[tlv.Blob] { 175 return i.resolutionBlob 176 } 177 178 // inputOpts contains options for constructing a new input. 179 type inputOpts struct { 180 // resolutionBlob is an optional blob that can be used to resolve an 181 // input. 182 resolutionBlob fn.Option[tlv.Blob] 183 } 184 185 // defaultInputOpts returns a new inputOpts with default values. 186 func defaultInputOpts() *inputOpts { 187 return &inputOpts{} 188 } 189 190 // InputOpt is a functional option that can be used to modify the default input 191 // options. 192 type InputOpt func(*inputOpts) //nolint:revive 193 194 // WithResolutionBlob is an option that can be used to set a resolution blob on 195 // for an input. 196 func WithResolutionBlob(b fn.Option[tlv.Blob]) InputOpt { 197 return func(o *inputOpts) { 198 o.resolutionBlob = b 199 } 200 } 201 202 // BaseInput contains all the information needed to sweep a basic 203 // output (CSV/CLTV/no time lock). 204 type BaseInput struct { 205 inputKit 206 } 207 208 // MakeBaseInput assembles a new BaseInput that can be used to construct a 209 // sweep transaction. 210 func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType, 211 signDescriptor *SignDescriptor, heightHint uint32, 212 unconfParent *TxInfo, opts ...InputOpt) BaseInput { 213 214 opt := defaultInputOpts() 215 for _, optF := range opts { 216 optF(opt) 217 } 218 219 return BaseInput{ 220 inputKit{ 221 outpoint: *outpoint, 222 witnessType: witnessType, 223 signDesc: *signDescriptor, 224 heightHint: heightHint, 225 unconfParent: unconfParent, 226 resolutionBlob: opt.resolutionBlob, 227 }, 228 } 229 } 230 231 // NewBaseInput allocates and assembles a new *BaseInput that can be used to 232 // construct a sweep transaction. 233 func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType, 234 signDescriptor *SignDescriptor, heightHint uint32, 235 opts ...InputOpt) *BaseInput { 236 237 input := MakeBaseInput( 238 outpoint, witnessType, signDescriptor, heightHint, nil, opts..., 239 ) 240 241 return &input 242 } 243 244 // NewCsvInput assembles a new csv-locked input that can be used to 245 // construct a sweep transaction. 246 func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType, 247 signDescriptor *SignDescriptor, heightHint uint32, 248 blockToMaturity uint32, opts ...InputOpt) *BaseInput { 249 250 input := MakeBaseInput( 251 outpoint, witnessType, signDescriptor, heightHint, nil, opts..., 252 ) 253 254 input.blockToMaturity = blockToMaturity 255 256 return &input 257 } 258 259 // NewCsvInputWithCltv assembles a new csv and cltv locked input that can be 260 // used to construct a sweep transaction. 261 func NewCsvInputWithCltv(outpoint *wire.OutPoint, witnessType WitnessType, 262 signDescriptor *SignDescriptor, heightHint uint32, 263 csvDelay uint32, cltvExpiry uint32, opts ...InputOpt) *BaseInput { 264 265 input := MakeBaseInput( 266 outpoint, witnessType, signDescriptor, heightHint, nil, opts..., 267 ) 268 269 input.blockToMaturity = csvDelay 270 input.cltvExpiry = cltvExpiry 271 272 return &input 273 } 274 275 // CraftInputScript returns a valid set of input scripts allowing this output 276 // to be spent. The returned input scripts should target the input at location 277 // txIndex within the passed transaction. The input scripts generated by this 278 // method support spending p2wkh, p2wsh, and also nested p2sh outputs. 279 func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx, 280 hashCache *txscript.TxSigHashes, 281 prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script, 282 error) { 283 284 signDesc := bi.SignDesc() 285 signDesc.PrevOutputFetcher = prevOutputFetcher 286 witnessFunc := bi.witnessType.WitnessGenerator(signer, signDesc) 287 288 return witnessFunc(txn, hashCache, txinIdx) 289 } 290 291 // Preimage returns the preimage for the input if it is an HTLC input. 292 func (bi *BaseInput) Preimage() fn.Option[lntypes.Preimage] { 293 return fn.None[lntypes.Preimage]() 294 } 295 296 // HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input 297 // is expected to reside on the commitment tx of the remote party and should 298 // not be a second level tx output. 299 type HtlcSucceedInput struct { 300 inputKit 301 302 preimage []byte 303 } 304 305 // MakeHtlcSucceedInput assembles a new redeem input that can be used to 306 // construct a sweep transaction. 307 func MakeHtlcSucceedInput(outpoint *wire.OutPoint, 308 signDescriptor *SignDescriptor, preimage []byte, heightHint, 309 blocksToMaturity uint32, opts ...InputOpt) HtlcSucceedInput { 310 311 input := MakeBaseInput( 312 outpoint, HtlcAcceptedRemoteSuccess, signDescriptor, 313 heightHint, nil, opts..., 314 ) 315 input.blockToMaturity = blocksToMaturity 316 317 return HtlcSucceedInput{ 318 inputKit: input.inputKit, 319 preimage: preimage, 320 } 321 } 322 323 // MakeTaprootHtlcSucceedInput creates a new HtlcSucceedInput that can be used 324 // to spend an HTLC output for a taproot channel on the remote party's 325 // commitment transaction. 326 func MakeTaprootHtlcSucceedInput(op *wire.OutPoint, signDesc *SignDescriptor, 327 preimage []byte, heightHint, blocksToMaturity uint32, 328 opts ...InputOpt) HtlcSucceedInput { 329 330 input := MakeBaseInput( 331 op, TaprootHtlcAcceptedRemoteSuccess, signDesc, 332 heightHint, nil, opts..., 333 ) 334 input.blockToMaturity = blocksToMaturity 335 336 return HtlcSucceedInput{ 337 inputKit: input.inputKit, 338 preimage: preimage, 339 } 340 } 341 342 // CraftInputScript returns a valid set of input scripts allowing this output 343 // to be spent. The returns input scripts should target the input at location 344 // txIndex within the passed transaction. The input scripts generated by this 345 // method support spending p2wkh, p2wsh, and also nested p2sh outputs. 346 func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx, 347 hashCache *txscript.TxSigHashes, 348 prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script, 349 error) { 350 351 desc := h.signDesc 352 desc.SigHashes = hashCache 353 desc.InputIndex = txinIdx 354 desc.PrevOutputFetcher = prevOutputFetcher 355 356 isTaproot := txscript.IsPayToTaproot(desc.Output.PkScript) 357 358 var ( 359 witness wire.TxWitness 360 err error 361 ) 362 if isTaproot { 363 if desc.ControlBlock == nil { 364 return nil, fmt.Errorf("ctrl block must be set") 365 } 366 367 desc.SignMethod = TaprootScriptSpendSignMethod 368 witness, err = SenderHTLCScriptTaprootRedeem( 369 signer, &desc, txn, h.preimage, nil, nil, 370 ) 371 } else { 372 witness, err = SenderHtlcSpendRedeem( 373 signer, &desc, txn, h.preimage, 374 ) 375 } 376 if err != nil { 377 return nil, err 378 } 379 380 return &Script{ 381 Witness: witness, 382 }, nil 383 } 384 385 // Preimage returns the preimage for the input if it is an HTLC input. 386 func (h *HtlcSucceedInput) Preimage() fn.Option[lntypes.Preimage] { 387 if len(h.preimage) == 0 { 388 return fn.None[lntypes.Preimage]() 389 } 390 391 return fn.Some(lntypes.Preimage(h.preimage)) 392 } 393 394 // HtlcSecondLevelAnchorInput is an input type used to spend HTLC outputs 395 // using a re-signed second level transaction, either via the timeout or success 396 // paths. 397 type HtlcSecondLevelAnchorInput struct { 398 inputKit 399 400 // SignedTx is the original second level transaction signed by the 401 // channel peer. 402 SignedTx *wire.MsgTx 403 404 // createWitness creates a witness allowing the passed transaction to 405 // spend the input. 406 createWitness func(signer Signer, txn *wire.MsgTx, 407 hashCache *txscript.TxSigHashes, 408 prevOutputFetcher txscript.PrevOutputFetcher, 409 txinIdx int) (wire.TxWitness, error) 410 411 preimage []byte 412 } 413 414 // RequiredTxOut returns the tx out needed to be present on the sweep tx for 415 // the spend of the input to be valid. 416 func (i *HtlcSecondLevelAnchorInput) RequiredTxOut() *wire.TxOut { 417 return i.SignedTx.TxOut[0] 418 } 419 420 // RequiredLockTime returns the locktime needed for the sweep tx for the spend 421 // of the input to be valid. For a second level HTLC timeout this will be the 422 // CLTV expiry, for HTLC success it will be zero. 423 func (i *HtlcSecondLevelAnchorInput) RequiredLockTime() (uint32, bool) { 424 return i.SignedTx.LockTime, true 425 } 426 427 // CraftInputScript returns a valid set of input scripts allowing this output 428 // to be spent. The returns input scripts should target the input at location 429 // txIndex within the passed transaction. The input scripts generated by this 430 // method support spending p2wkh, p2wsh, and also nested p2sh outputs. 431 func (i *HtlcSecondLevelAnchorInput) CraftInputScript(signer Signer, 432 txn *wire.MsgTx, hashCache *txscript.TxSigHashes, 433 prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script, 434 error) { 435 436 witness, err := i.createWitness( 437 signer, txn, hashCache, prevOutputFetcher, txinIdx, 438 ) 439 if err != nil { 440 return nil, err 441 } 442 443 return &Script{ 444 Witness: witness, 445 }, nil 446 } 447 448 // Preimage returns the preimage for the input if it is an HTLC input. 449 func (i *HtlcSecondLevelAnchorInput) Preimage() fn.Option[lntypes.Preimage] { 450 if len(i.preimage) == 0 { 451 return fn.None[lntypes.Preimage]() 452 } 453 454 return fn.Some(lntypes.Preimage(i.preimage)) 455 } 456 457 // MakeHtlcSecondLevelTimeoutAnchorInput creates an input allowing the sweeper 458 // to spend the HTLC output on our commit using the second level timeout 459 // transaction. 460 func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx, 461 signDetails *SignDetails, heightHint uint32, 462 opts ...InputOpt) HtlcSecondLevelAnchorInput { 463 464 // Spend an HTLC output on our local commitment tx using the 465 // 2nd timeout transaction. 466 createWitness := func(signer Signer, txn *wire.MsgTx, 467 hashCache *txscript.TxSigHashes, 468 prevOutputFetcher txscript.PrevOutputFetcher, 469 txinIdx int) (wire.TxWitness, error) { 470 471 desc := signDetails.SignDesc 472 desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher) 473 desc.InputIndex = txinIdx 474 desc.PrevOutputFetcher = prevOutputFetcher 475 476 return SenderHtlcSpendTimeout( 477 signDetails.PeerSig, signDetails.SigHashType, signer, 478 &desc, txn, 479 ) 480 } 481 482 input := MakeBaseInput( 483 &signedTx.TxIn[0].PreviousOutPoint, 484 HtlcOfferedTimeoutSecondLevelInputConfirmed, 485 &signDetails.SignDesc, heightHint, nil, opts..., 486 ) 487 input.blockToMaturity = 1 488 489 return HtlcSecondLevelAnchorInput{ 490 inputKit: input.inputKit, 491 SignedTx: signedTx, 492 createWitness: createWitness, 493 } 494 } 495 496 // MakeHtlcSecondLevelTimeoutTaprootInput creates an input that allows the 497 // sweeper to spend an HTLC output to the second level on our commitment 498 // transaction. The sweeper is also able to generate witnesses on demand to 499 // sweep the second level HTLC aggregated with other transactions. 500 func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx, 501 signDetails *SignDetails, 502 heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput { 503 504 createWitness := func(signer Signer, txn *wire.MsgTx, 505 hashCache *txscript.TxSigHashes, 506 prevOutputFetcher txscript.PrevOutputFetcher, 507 txinIdx int) (wire.TxWitness, error) { 508 509 desc := signDetails.SignDesc 510 if desc.ControlBlock == nil { 511 return nil, fmt.Errorf("ctrl block must be set") 512 } 513 514 desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher) 515 desc.InputIndex = txinIdx 516 desc.PrevOutputFetcher = prevOutputFetcher 517 518 desc.SignMethod = TaprootScriptSpendSignMethod 519 520 return SenderHTLCScriptTaprootTimeout( 521 signDetails.PeerSig, signDetails.SigHashType, signer, 522 &desc, txn, nil, nil, 523 ) 524 } 525 526 input := MakeBaseInput( 527 &signedTx.TxIn[0].PreviousOutPoint, 528 TaprootHtlcLocalOfferedTimeout, 529 &signDetails.SignDesc, heightHint, nil, opts..., 530 ) 531 input.blockToMaturity = 1 532 533 return HtlcSecondLevelAnchorInput{ 534 inputKit: input.inputKit, 535 SignedTx: signedTx, 536 createWitness: createWitness, 537 } 538 } 539 540 // MakeHtlcSecondLevelSuccessAnchorInput creates an input allowing the sweeper 541 // to spend the HTLC output on our commit using the second level success 542 // transaction. 543 func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx, 544 signDetails *SignDetails, preimage lntypes.Preimage, 545 heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput { 546 547 // Spend an HTLC output on our local commitment tx using the 2nd 548 // success transaction. 549 createWitness := func(signer Signer, txn *wire.MsgTx, 550 hashCache *txscript.TxSigHashes, 551 prevOutputFetcher txscript.PrevOutputFetcher, 552 txinIdx int) (wire.TxWitness, error) { 553 554 desc := signDetails.SignDesc 555 desc.SigHashes = hashCache 556 desc.InputIndex = txinIdx 557 desc.PrevOutputFetcher = prevOutputFetcher 558 559 return ReceiverHtlcSpendRedeem( 560 signDetails.PeerSig, signDetails.SigHashType, 561 preimage[:], signer, &desc, txn, 562 ) 563 } 564 input := MakeBaseInput( 565 &signedTx.TxIn[0].PreviousOutPoint, 566 HtlcAcceptedSuccessSecondLevelInputConfirmed, 567 &signDetails.SignDesc, heightHint, nil, opts..., 568 ) 569 input.blockToMaturity = 1 570 571 return HtlcSecondLevelAnchorInput{ 572 SignedTx: signedTx, 573 inputKit: input.inputKit, 574 createWitness: createWitness, 575 preimage: preimage[:], 576 } 577 } 578 579 // MakeHtlcSecondLevelSuccessTaprootInput creates an input that allows the 580 // sweeper to spend an HTLC output to the second level on our taproot 581 // commitment transaction. 582 func MakeHtlcSecondLevelSuccessTaprootInput(signedTx *wire.MsgTx, 583 signDetails *SignDetails, preimage lntypes.Preimage, 584 heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput { 585 586 createWitness := func(signer Signer, txn *wire.MsgTx, 587 hashCache *txscript.TxSigHashes, 588 prevOutputFetcher txscript.PrevOutputFetcher, 589 txinIdx int) (wire.TxWitness, error) { 590 591 desc := signDetails.SignDesc 592 if desc.ControlBlock == nil { 593 return nil, fmt.Errorf("ctrl block must be set") 594 } 595 596 desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher) 597 desc.InputIndex = txinIdx 598 desc.PrevOutputFetcher = prevOutputFetcher 599 600 desc.SignMethod = TaprootScriptSpendSignMethod 601 602 return ReceiverHTLCScriptTaprootRedeem( 603 signDetails.PeerSig, signDetails.SigHashType, 604 preimage[:], signer, &desc, txn, nil, nil, 605 ) 606 } 607 608 input := MakeBaseInput( 609 &signedTx.TxIn[0].PreviousOutPoint, 610 TaprootHtlcAcceptedLocalSuccess, 611 &signDetails.SignDesc, heightHint, nil, opts..., 612 ) 613 input.blockToMaturity = 1 614 615 return HtlcSecondLevelAnchorInput{ 616 inputKit: input.inputKit, 617 SignedTx: signedTx, 618 createWitness: createWitness, 619 preimage: preimage[:], 620 } 621 } 622 623 // Compile-time constraints to ensure each input struct implement the Input 624 // interface. 625 var _ Input = (*BaseInput)(nil) 626 var _ Input = (*HtlcSucceedInput)(nil) 627 var _ Input = (*HtlcSecondLevelAnchorInput)(nil)