• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 13536249039

26 Feb 2025 03:42AM UTC coverage: 57.462% (-1.4%) from 58.835%
13536249039

Pull #8453

github

Roasbeef
peer: update chooseDeliveryScript to gen script if needed

In this commit, we update `chooseDeliveryScript` to generate a new
script if needed. This allows us to fold in a few other lines that
always followed this function into this expanded function.

The tests have been updated accordingly.
Pull Request #8453: [4/4] - multi: integrate new rbf coop close FSM into the existing peer flow

275 of 1318 new or added lines in 22 files covered. (20.86%)

19521 existing lines in 257 files now uncovered.

103858 of 180741 relevant lines covered (57.46%)

24750.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.78
/input/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.
UNCOV
87
func (t *TxInfo) String() string {
×
UNCOV
88
        return fmt.Sprintf("fee=%v, weight=%v", t.Fee, t.Weight)
×
UNCOV
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 {
2,929✔
127
        return i.outpoint
2,929✔
128
}
2,929✔
129

130
// RequiredTxOut returns a nil for the base input type.
131
func (i *inputKit) RequiredTxOut() *wire.TxOut {
141✔
132
        return nil
141✔
133
}
141✔
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) {
26✔
139
        return i.cltvExpiry, i.cltvExpiry > 0
26✔
140
}
26✔
141

142
// WitnessType returns the type of witness that must be generated to spend the
143
// breached output.
144
func (i *inputKit) WitnessType() WitnessType {
1,530✔
145
        return i.witnessType
1,530✔
146
}
1,530✔
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 {
2,889✔
151
        return &i.signDesc
2,889✔
152
}
2,889✔
153

154
// HeightHint returns the minimum height at which a confirmed spending
155
// tx can occur.
156
func (i *inputKit) HeightHint() uint32 {
5✔
157
        return i.heightHint
5✔
158
}
5✔
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 {
1,417✔
164
        return i.blockToMaturity
1,417✔
165
}
1,417✔
166

167
// Cpfp returns information about a possibly unconfirmed parent tx.
168
func (i *inputKit) UnconfParent() *TxInfo {
66✔
169
        return i.unconfParent
66✔
170
}
66✔
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] {
10✔
175
        return i.resolutionBlob
10✔
176
}
10✔
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 {
1,133✔
187
        return &inputOpts{}
1,133✔
188
}
1,133✔
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 {
8✔
197
        return func(o *inputOpts) {
16✔
198
                o.resolutionBlob = b
8✔
199
        }
8✔
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 {
1,133✔
213

1,133✔
214
        opt := defaultInputOpts()
1,133✔
215
        for _, optF := range opts {
1,141✔
216
                optF(opt)
8✔
217
        }
8✔
218

219
        return BaseInput{
1,133✔
220
                inputKit{
1,133✔
221
                        outpoint:       *outpoint,
1,133✔
222
                        witnessType:    witnessType,
1,133✔
223
                        signDesc:       *signDescriptor,
1,133✔
224
                        heightHint:     heightHint,
1,133✔
225
                        unconfParent:   unconfParent,
1,133✔
226
                        resolutionBlob: opt.resolutionBlob,
1,133✔
227
                },
1,133✔
228
        }
1,133✔
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 {
567✔
236

567✔
237
        input := MakeBaseInput(
567✔
238
                outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
567✔
239
        )
567✔
240

567✔
241
        return &input
567✔
242
}
567✔
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 {
510✔
249

510✔
250
        input := MakeBaseInput(
510✔
251
                outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
510✔
252
        )
510✔
253

510✔
254
        input.blockToMaturity = blockToMaturity
510✔
255

510✔
256
        return &input
510✔
257
}
510✔
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 {
4✔
264

4✔
265
        input := MakeBaseInput(
4✔
266
                outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
4✔
267
        )
4✔
268

4✔
269
        input.blockToMaturity = csvDelay
4✔
270
        input.cltvExpiry = cltvExpiry
4✔
271

4✔
272
        return &input
4✔
273
}
4✔
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) {
1,417✔
283

1,417✔
284
        signDesc := bi.SignDesc()
1,417✔
285
        signDesc.PrevOutputFetcher = prevOutputFetcher
1,417✔
286
        witnessFunc := bi.witnessType.WitnessGenerator(signer, signDesc)
1,417✔
287

1,417✔
288
        return witnessFunc(txn, hashCache, txinIdx)
1,417✔
289
}
1,417✔
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 {
4✔
310

4✔
311
        input := MakeBaseInput(
4✔
312
                outpoint, HtlcAcceptedRemoteSuccess, signDescriptor,
4✔
313
                heightHint, nil, opts...,
4✔
314
        )
4✔
315
        input.blockToMaturity = blocksToMaturity
4✔
316

4✔
317
        return HtlcSucceedInput{
4✔
318
                inputKit: input.inputKit,
4✔
319
                preimage: preimage,
4✔
320
        }
4✔
321
}
4✔
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,
UNCOV
328
        opts ...InputOpt) HtlcSucceedInput {
×
UNCOV
329

×
UNCOV
330
        input := MakeBaseInput(
×
UNCOV
331
                op, TaprootHtlcAcceptedRemoteSuccess, signDesc,
×
UNCOV
332
                heightHint, nil, opts...,
×
UNCOV
333
        )
×
UNCOV
334
        input.blockToMaturity = blocksToMaturity
×
UNCOV
335

×
UNCOV
336
        return HtlcSucceedInput{
×
UNCOV
337
                inputKit: input.inputKit,
×
UNCOV
338
                preimage: preimage,
×
UNCOV
339
        }
×
UNCOV
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,
UNCOV
349
        error) {
×
UNCOV
350

×
UNCOV
351
        desc := h.signDesc
×
UNCOV
352
        desc.SigHashes = hashCache
×
UNCOV
353
        desc.InputIndex = txinIdx
×
UNCOV
354
        desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
355

×
UNCOV
356
        isTaproot := txscript.IsPayToTaproot(desc.Output.PkScript)
×
UNCOV
357

×
UNCOV
358
        var (
×
UNCOV
359
                witness wire.TxWitness
×
UNCOV
360
                err     error
×
UNCOV
361
        )
×
UNCOV
362
        if isTaproot {
×
UNCOV
363
                if desc.ControlBlock == nil {
×
364
                        return nil, fmt.Errorf("ctrl block must be set")
×
365
                }
×
366

UNCOV
367
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
368
                witness, err = SenderHTLCScriptTaprootRedeem(
×
UNCOV
369
                        signer, &desc, txn, h.preimage, nil, nil,
×
UNCOV
370
                )
×
UNCOV
371
        } else {
×
UNCOV
372
                witness, err = SenderHtlcSpendRedeem(
×
UNCOV
373
                        signer, &desc, txn, h.preimage,
×
UNCOV
374
                )
×
UNCOV
375
        }
×
UNCOV
376
        if err != nil {
×
377
                return nil, err
×
378
        }
×
379

UNCOV
380
        return &Script{
×
UNCOV
381
                Witness: witness,
×
UNCOV
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.
UNCOV
416
func (i *HtlcSecondLevelAnchorInput) RequiredTxOut() *wire.TxOut {
×
UNCOV
417
        return i.SignedTx.TxOut[0]
×
UNCOV
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.
UNCOV
423
func (i *HtlcSecondLevelAnchorInput) RequiredLockTime() (uint32, bool) {
×
UNCOV
424
        return i.SignedTx.LockTime, true
×
UNCOV
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,
UNCOV
434
        error) {
×
UNCOV
435

×
UNCOV
436
        witness, err := i.createWitness(
×
UNCOV
437
                signer, txn, hashCache, prevOutputFetcher, txinIdx,
×
UNCOV
438
        )
×
UNCOV
439
        if err != nil {
×
440
                return nil, err
×
441
        }
×
442

UNCOV
443
        return &Script{
×
UNCOV
444
                Witness: witness,
×
UNCOV
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 {
2✔
463

2✔
464
        // Spend an HTLC output on our local commitment tx using the
2✔
465
        // 2nd timeout transaction.
2✔
466
        createWitness := func(signer Signer, txn *wire.MsgTx,
2✔
467
                hashCache *txscript.TxSigHashes,
2✔
468
                prevOutputFetcher txscript.PrevOutputFetcher,
2✔
469
                txinIdx int) (wire.TxWitness, error) {
2✔
UNCOV
470

×
UNCOV
471
                desc := signDetails.SignDesc
×
UNCOV
472
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
473
                desc.InputIndex = txinIdx
×
UNCOV
474
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
475

×
UNCOV
476
                return SenderHtlcSpendTimeout(
×
UNCOV
477
                        signDetails.PeerSig, signDetails.SigHashType, signer,
×
UNCOV
478
                        &desc, txn,
×
UNCOV
479
                )
×
UNCOV
480
        }
×
481

482
        input := MakeBaseInput(
2✔
483
                &signedTx.TxIn[0].PreviousOutPoint,
2✔
484
                HtlcOfferedTimeoutSecondLevelInputConfirmed,
2✔
485
                &signDetails.SignDesc, heightHint, nil, opts...,
2✔
486
        )
2✔
487
        input.blockToMaturity = 1
2✔
488

2✔
489
        return HtlcSecondLevelAnchorInput{
2✔
490
                inputKit:      input.inputKit,
2✔
491
                SignedTx:      signedTx,
2✔
492
                createWitness: createWitness,
2✔
493
        }
2✔
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,
UNCOV
502
        heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
×
UNCOV
503

×
UNCOV
504
        createWitness := func(signer Signer, txn *wire.MsgTx,
×
UNCOV
505
                hashCache *txscript.TxSigHashes,
×
UNCOV
506
                prevOutputFetcher txscript.PrevOutputFetcher,
×
UNCOV
507
                txinIdx int) (wire.TxWitness, error) {
×
UNCOV
508

×
UNCOV
509
                desc := signDetails.SignDesc
×
UNCOV
510
                if desc.ControlBlock == nil {
×
511
                        return nil, fmt.Errorf("ctrl block must be set")
×
512
                }
×
513

UNCOV
514
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
515
                desc.InputIndex = txinIdx
×
UNCOV
516
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
517

×
UNCOV
518
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
519

×
UNCOV
520
                return SenderHTLCScriptTaprootTimeout(
×
UNCOV
521
                        signDetails.PeerSig, signDetails.SigHashType, signer,
×
UNCOV
522
                        &desc, txn, nil, nil,
×
UNCOV
523
                )
×
524
        }
525

UNCOV
526
        input := MakeBaseInput(
×
UNCOV
527
                &signedTx.TxIn[0].PreviousOutPoint,
×
UNCOV
528
                TaprootHtlcLocalOfferedTimeout,
×
UNCOV
529
                &signDetails.SignDesc, heightHint, nil, opts...,
×
UNCOV
530
        )
×
UNCOV
531
        input.blockToMaturity = 1
×
UNCOV
532

×
UNCOV
533
        return HtlcSecondLevelAnchorInput{
×
UNCOV
534
                inputKit:      input.inputKit,
×
UNCOV
535
                SignedTx:      signedTx,
×
UNCOV
536
                createWitness: createWitness,
×
UNCOV
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 {
1✔
546

1✔
547
        // Spend an HTLC output on our local commitment tx using the 2nd
1✔
548
        // success transaction.
1✔
549
        createWitness := func(signer Signer, txn *wire.MsgTx,
1✔
550
                hashCache *txscript.TxSigHashes,
1✔
551
                prevOutputFetcher txscript.PrevOutputFetcher,
1✔
552
                txinIdx int) (wire.TxWitness, error) {
1✔
UNCOV
553

×
UNCOV
554
                desc := signDetails.SignDesc
×
UNCOV
555
                desc.SigHashes = hashCache
×
UNCOV
556
                desc.InputIndex = txinIdx
×
UNCOV
557
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
558

×
UNCOV
559
                return ReceiverHtlcSpendRedeem(
×
UNCOV
560
                        signDetails.PeerSig, signDetails.SigHashType,
×
UNCOV
561
                        preimage[:], signer, &desc, txn,
×
UNCOV
562
                )
×
UNCOV
563
        }
×
564
        input := MakeBaseInput(
1✔
565
                &signedTx.TxIn[0].PreviousOutPoint,
1✔
566
                HtlcAcceptedSuccessSecondLevelInputConfirmed,
1✔
567
                &signDetails.SignDesc, heightHint, nil, opts...,
1✔
568
        )
1✔
569
        input.blockToMaturity = 1
1✔
570

1✔
571
        return HtlcSecondLevelAnchorInput{
1✔
572
                SignedTx:      signedTx,
1✔
573
                inputKit:      input.inputKit,
1✔
574
                createWitness: createWitness,
1✔
575
                preimage:      preimage[:],
1✔
576
        }
1✔
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,
UNCOV
584
        heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
×
UNCOV
585

×
UNCOV
586
        createWitness := func(signer Signer, txn *wire.MsgTx,
×
UNCOV
587
                hashCache *txscript.TxSigHashes,
×
UNCOV
588
                prevOutputFetcher txscript.PrevOutputFetcher,
×
UNCOV
589
                txinIdx int) (wire.TxWitness, error) {
×
UNCOV
590

×
UNCOV
591
                desc := signDetails.SignDesc
×
UNCOV
592
                if desc.ControlBlock == nil {
×
593
                        return nil, fmt.Errorf("ctrl block must be set")
×
594
                }
×
595

UNCOV
596
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
597
                desc.InputIndex = txinIdx
×
UNCOV
598
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
599

×
UNCOV
600
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
601

×
UNCOV
602
                return ReceiverHTLCScriptTaprootRedeem(
×
UNCOV
603
                        signDetails.PeerSig, signDetails.SigHashType,
×
UNCOV
604
                        preimage[:], signer, &desc, txn, nil, nil,
×
UNCOV
605
                )
×
606
        }
607

UNCOV
608
        input := MakeBaseInput(
×
UNCOV
609
                &signedTx.TxIn[0].PreviousOutPoint,
×
UNCOV
610
                TaprootHtlcAcceptedLocalSuccess,
×
UNCOV
611
                &signDetails.SignDesc, heightHint, nil, opts...,
×
UNCOV
612
        )
×
UNCOV
613
        input.blockToMaturity = 1
×
UNCOV
614

×
UNCOV
615
        return HtlcSecondLevelAnchorInput{
×
UNCOV
616
                inputKit:      input.inputKit,
×
UNCOV
617
                SignedTx:      signedTx,
×
UNCOV
618
                createWitness: createWitness,
×
UNCOV
619
                preimage:      preimage[:],
×
UNCOV
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)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc