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

lightningnetwork / lnd / 13440912774

20 Feb 2025 05:14PM UTC coverage: 57.697% (-1.1%) from 58.802%
13440912774

Pull #9535

github

guggero
GitHub: remove duplicate caching

Turns out that actions/setup-go starting with @v4 also adds caching.
With that, our cache size on disk has almost doubled, leading to the
GitHub runner running out of space in certain situation.
We fix that by disabling the automated caching since we already have our
own, custom-tailored version.
Pull Request #9535: GitHub: remove duplicate caching

103519 of 179417 relevant lines covered (57.7%)

24825.3 hits per line

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

44.81
/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.
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 {
2,912✔
127
        return i.outpoint
2,912✔
128
}
2,912✔
129

130
// RequiredTxOut returns a nil for the base input type.
131
func (i *inputKit) RequiredTxOut() *wire.TxOut {
135✔
132
        return nil
135✔
133
}
135✔
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) {
25✔
139
        return i.cltvExpiry, i.cltvExpiry > 0
25✔
140
}
25✔
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,522✔
145
        return i.witnessType
1,522✔
146
}
1,522✔
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,881✔
151
        return &i.signDesc
2,881✔
152
}
2,881✔
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 {
1,416✔
164
        return i.blockToMaturity
1,416✔
165
}
1,416✔
166

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

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

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

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

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