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

lightningnetwork / lnd / 11374676620

16 Oct 2024 10:12PM UTC coverage: 57.847% (-0.9%) from 58.78%
11374676620

Pull #9148

github

ProofOfKeags
lnwire: change DynPropose/DynCommit TLV numbers to align with spec
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

353 of 634 new or added lines in 12 files covered. (55.68%)

18908 existing lines in 242 files now uncovered.

99301 of 171661 relevant lines covered (57.85%)

37037.59 hits per line

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

46.6
/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"
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

74
// TxInfo describes properties of a parent tx that are relevant for CPFP.
75
type TxInfo struct {
76
        // Fee is the fee of the tx.
77
        Fee btcutil.Amount
78

79
        // Weight is the weight of the tx.
80
        Weight lntypes.WeightUnit
81
}
82

83
// String returns a human readable version of the tx info.
UNCOV
84
func (t *TxInfo) String() string {
×
UNCOV
85
        return fmt.Sprintf("fee=%v, weight=%v", t.Fee, t.Weight)
×
UNCOV
86
}
×
87

88
// SignDetails is a struct containing information needed to resign certain
89
// inputs. It is used to re-sign 2nd level HTLC transactions that uses the
90
// SINGLE|ANYONECANPAY sighash type, as we have a signature provided by our
91
// peer, but we can aggregate multiple of these 2nd level transactions into a
92
// new transaction, that needs to be signed by us.
93
type SignDetails struct {
94
        // SignDesc is the sign descriptor needed for us to sign the input.
95
        SignDesc SignDescriptor
96

97
        // PeerSig is the peer's signature for this input.
98
        PeerSig Signature
99

100
        // SigHashType is the sighash signed by the peer.
101
        SigHashType txscript.SigHashType
102
}
103

104
type inputKit struct {
105
        outpoint        wire.OutPoint
106
        witnessType     WitnessType
107
        signDesc        SignDescriptor
108
        heightHint      uint32
109
        blockToMaturity uint32
110
        cltvExpiry      uint32
111

112
        // unconfParent contains information about a potential unconfirmed
113
        // parent transaction.
114
        unconfParent *TxInfo
115

116
        // resolutionBlob is an optional blob that can be used to resolve an
117
        // input.
118
        resolutionBlob fn.Option[tlv.Blob]
119
}
120

121
// OutPoint returns the breached output's identifier that is to be included as
122
// a transaction input.
123
func (i *inputKit) OutPoint() wire.OutPoint {
2,914✔
124
        return i.outpoint
2,914✔
125
}
2,914✔
126

127
// RequiredTxOut returns a nil for the base input type.
128
func (i *inputKit) RequiredTxOut() *wire.TxOut {
134✔
129
        return nil
134✔
130
}
134✔
131

132
// RequiredLockTime returns whether this input commits to a tx locktime that
133
// must be used in the transaction including it. This will be false for the
134
// base input type since we can re-sign for any lock time.
135
func (i *inputKit) RequiredLockTime() (uint32, bool) {
25✔
136
        return i.cltvExpiry, i.cltvExpiry > 0
25✔
137
}
25✔
138

139
// WitnessType returns the type of witness that must be generated to spend the
140
// breached output.
141
func (i *inputKit) WitnessType() WitnessType {
1,521✔
142
        return i.witnessType
1,521✔
143
}
1,521✔
144

145
// SignDesc returns the breached output's SignDescriptor, which is used during
146
// signing to compute the witness.
147
func (i *inputKit) SignDesc() *SignDescriptor {
2,878✔
148
        return &i.signDesc
2,878✔
149
}
2,878✔
150

151
// HeightHint returns the minimum height at which a confirmed spending
152
// tx can occur.
UNCOV
153
func (i *inputKit) HeightHint() uint32 {
×
UNCOV
154
        return i.heightHint
×
UNCOV
155
}
×
156

157
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
158
// must be built on top of the confirmation height before the output can be
159
// spent. For non-CSV locked inputs this is always zero.
160
func (i *inputKit) BlocksToMaturity() uint32 {
1,416✔
161
        return i.blockToMaturity
1,416✔
162
}
1,416✔
163

164
// Cpfp returns information about a possibly unconfirmed parent tx.
165
func (i *inputKit) UnconfParent() *TxInfo {
62✔
166
        return i.unconfParent
62✔
167
}
62✔
168

169
// ResolutionBlob returns a special opaque blob to be used to sweep/resolve
170
// this input.
171
func (i *inputKit) ResolutionBlob() fn.Option[tlv.Blob] {
7✔
172
        return i.resolutionBlob
7✔
173
}
7✔
174

175
// inputOpts contains options for constructing a new input.
176
type inputOpts struct {
177
        // resolutionBlob is an optional blob that can be used to resolve an
178
        // input.
179
        resolutionBlob fn.Option[tlv.Blob]
180
}
181

182
// defaultInputOpts returns a new inputOpts with default values.
183
func defaultInputOpts() *inputOpts {
1,120✔
184
        return &inputOpts{}
1,120✔
185
}
1,120✔
186

187
// InputOpt is a functional option that can be used to modify the default input
188
// options.
189
type InputOpt func(*inputOpts) //nolint:revive
190

191
// WithResolutionBlob is an option that can be used to set a resolution blob on
192
// for an input.
193
func WithResolutionBlob(b fn.Option[tlv.Blob]) InputOpt {
3✔
194
        return func(o *inputOpts) {
6✔
195
                o.resolutionBlob = b
3✔
196
        }
3✔
197
}
198

199
// BaseInput contains all the information needed to sweep a basic
200
// output (CSV/CLTV/no time lock).
201
type BaseInput struct {
202
        inputKit
203
}
204

205
// MakeBaseInput assembles a new BaseInput that can be used to construct a
206
// sweep transaction.
207
func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
208
        signDescriptor *SignDescriptor, heightHint uint32,
209
        unconfParent *TxInfo, opts ...InputOpt) BaseInput {
1,120✔
210

1,120✔
211
        opt := defaultInputOpts()
1,120✔
212
        for _, optF := range opts {
1,123✔
213
                optF(opt)
3✔
214
        }
3✔
215

216
        return BaseInput{
1,120✔
217
                inputKit{
1,120✔
218
                        outpoint:       *outpoint,
1,120✔
219
                        witnessType:    witnessType,
1,120✔
220
                        signDesc:       *signDescriptor,
1,120✔
221
                        heightHint:     heightHint,
1,120✔
222
                        unconfParent:   unconfParent,
1,120✔
223
                        resolutionBlob: opt.resolutionBlob,
1,120✔
224
                },
1,120✔
225
        }
1,120✔
226
}
227

228
// NewBaseInput allocates and assembles a new *BaseInput that can be used to
229
// construct a sweep transaction.
230
func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
231
        signDescriptor *SignDescriptor, heightHint uint32,
232
        opts ...InputOpt) *BaseInput {
566✔
233

566✔
234
        input := MakeBaseInput(
566✔
235
                outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
566✔
236
        )
566✔
237

566✔
238
        return &input
566✔
239
}
566✔
240

241
// NewCsvInput assembles a new csv-locked input that can be used to
242
// construct a sweep transaction.
243
func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType,
244
        signDescriptor *SignDescriptor, heightHint uint32,
245
        blockToMaturity uint32, opts ...InputOpt) *BaseInput {
509✔
246

509✔
247
        input := MakeBaseInput(
509✔
248
                outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
509✔
249
        )
509✔
250

509✔
251
        input.blockToMaturity = blockToMaturity
509✔
252

509✔
253
        return &input
509✔
254
}
509✔
255

256
// NewCsvInputWithCltv assembles a new csv and cltv locked input that can be
257
// used to construct a sweep transaction.
258
func NewCsvInputWithCltv(outpoint *wire.OutPoint, witnessType WitnessType,
259
        signDescriptor *SignDescriptor, heightHint uint32,
260
        csvDelay uint32, cltvExpiry uint32, opts ...InputOpt) *BaseInput {
4✔
261

4✔
262
        input := MakeBaseInput(
4✔
263
                outpoint, witnessType, signDescriptor, heightHint, nil, opts...,
4✔
264
        )
4✔
265

4✔
266
        input.blockToMaturity = csvDelay
4✔
267
        input.cltvExpiry = cltvExpiry
4✔
268

4✔
269
        return &input
4✔
270
}
4✔
271

272
// CraftInputScript returns a valid set of input scripts allowing this output
273
// to be spent. The returned input scripts should target the input at location
274
// txIndex within the passed transaction. The input scripts generated by this
275
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
276
func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
277
        hashCache *txscript.TxSigHashes,
278
        prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script,
279
        error) {
1,416✔
280

1,416✔
281
        signDesc := bi.SignDesc()
1,416✔
282
        signDesc.PrevOutputFetcher = prevOutputFetcher
1,416✔
283
        witnessFunc := bi.witnessType.WitnessGenerator(signer, signDesc)
1,416✔
284

1,416✔
285
        return witnessFunc(txn, hashCache, txinIdx)
1,416✔
286
}
1,416✔
287

288
// HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input
289
// is expected to reside on the commitment tx of the remote party and should
290
// not be a second level tx output.
291
type HtlcSucceedInput struct {
292
        inputKit
293

294
        preimage []byte
295
}
296

297
// MakeHtlcSucceedInput assembles a new redeem input that can be used to
298
// construct a sweep transaction.
299
func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
300
        signDescriptor *SignDescriptor, preimage []byte, heightHint,
301
        blocksToMaturity uint32, opts ...InputOpt) HtlcSucceedInput {
1✔
302

1✔
303
        input := MakeBaseInput(
1✔
304
                outpoint, HtlcAcceptedRemoteSuccess, signDescriptor,
1✔
305
                heightHint, nil, opts...,
1✔
306
        )
1✔
307
        input.blockToMaturity = blocksToMaturity
1✔
308

1✔
309
        return HtlcSucceedInput{
1✔
310
                inputKit: input.inputKit,
1✔
311
                preimage: preimage,
1✔
312
        }
1✔
313
}
1✔
314

315
// MakeTaprootHtlcSucceedInput creates a new HtlcSucceedInput that can be used
316
// to spend an HTLC output for a taproot channel on the remote party's
317
// commitment transaction.
318
func MakeTaprootHtlcSucceedInput(op *wire.OutPoint, signDesc *SignDescriptor,
319
        preimage []byte, heightHint, blocksToMaturity uint32,
UNCOV
320
        opts ...InputOpt) HtlcSucceedInput {
×
UNCOV
321

×
UNCOV
322
        input := MakeBaseInput(
×
UNCOV
323
                op, TaprootHtlcAcceptedRemoteSuccess, signDesc,
×
UNCOV
324
                heightHint, nil, opts...,
×
UNCOV
325
        )
×
UNCOV
326
        input.blockToMaturity = blocksToMaturity
×
UNCOV
327

×
UNCOV
328
        return HtlcSucceedInput{
×
UNCOV
329
                inputKit: input.inputKit,
×
UNCOV
330
                preimage: preimage,
×
UNCOV
331
        }
×
UNCOV
332
}
×
333

334
// CraftInputScript returns a valid set of input scripts allowing this output
335
// to be spent. The returns input scripts should target the input at location
336
// txIndex within the passed transaction. The input scripts generated by this
337
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
338
func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
339
        hashCache *txscript.TxSigHashes,
340
        prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script,
UNCOV
341
        error) {
×
UNCOV
342

×
UNCOV
343
        desc := h.signDesc
×
UNCOV
344
        desc.SigHashes = hashCache
×
UNCOV
345
        desc.InputIndex = txinIdx
×
UNCOV
346
        desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
347

×
UNCOV
348
        isTaproot := txscript.IsPayToTaproot(desc.Output.PkScript)
×
UNCOV
349

×
UNCOV
350
        var (
×
UNCOV
351
                witness wire.TxWitness
×
UNCOV
352
                err     error
×
UNCOV
353
        )
×
UNCOV
354
        if isTaproot {
×
UNCOV
355
                if desc.ControlBlock == nil {
×
356
                        return nil, fmt.Errorf("ctrl block must be set")
×
357
                }
×
358

UNCOV
359
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
360

×
UNCOV
361
                witness, err = SenderHTLCScriptTaprootRedeem(
×
UNCOV
362
                        signer, &desc, txn, h.preimage, nil, nil,
×
UNCOV
363
                )
×
UNCOV
364
        } else {
×
UNCOV
365
                witness, err = SenderHtlcSpendRedeem(
×
UNCOV
366
                        signer, &desc, txn, h.preimage,
×
UNCOV
367
                )
×
UNCOV
368
        }
×
UNCOV
369
        if err != nil {
×
370
                return nil, err
×
371
        }
×
372

UNCOV
373
        return &Script{
×
UNCOV
374
                Witness: witness,
×
UNCOV
375
        }, nil
×
376
}
377

378
// HtlcSecondLevelAnchorInput is an input type used to spend HTLC outputs
379
// using a re-signed second level transaction, either via the timeout or success
380
// paths.
381
type HtlcSecondLevelAnchorInput struct {
382
        inputKit
383

384
        // SignedTx is the original second level transaction signed by the
385
        // channel peer.
386
        SignedTx *wire.MsgTx
387

388
        // createWitness creates a witness allowing the passed transaction to
389
        // spend the input.
390
        createWitness func(signer Signer, txn *wire.MsgTx,
391
                hashCache *txscript.TxSigHashes,
392
                prevOutputFetcher txscript.PrevOutputFetcher,
393
                txinIdx int) (wire.TxWitness, error)
394
}
395

396
// RequiredTxOut returns the tx out needed to be present on the sweep tx for
397
// the spend of the input to be valid.
UNCOV
398
func (i *HtlcSecondLevelAnchorInput) RequiredTxOut() *wire.TxOut {
×
UNCOV
399
        return i.SignedTx.TxOut[0]
×
UNCOV
400
}
×
401

402
// RequiredLockTime returns the locktime needed for the sweep tx for the spend
403
// of the input to be valid. For a second level HTLC timeout this will be the
404
// CLTV expiry, for HTLC success it will be zero.
UNCOV
405
func (i *HtlcSecondLevelAnchorInput) RequiredLockTime() (uint32, bool) {
×
UNCOV
406
        return i.SignedTx.LockTime, true
×
UNCOV
407
}
×
408

409
// CraftInputScript returns a valid set of input scripts allowing this output
410
// to be spent. The returns input scripts should target the input at location
411
// txIndex within the passed transaction. The input scripts generated by this
412
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
413
func (i *HtlcSecondLevelAnchorInput) CraftInputScript(signer Signer,
414
        txn *wire.MsgTx, hashCache *txscript.TxSigHashes,
415
        prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script,
UNCOV
416
        error) {
×
UNCOV
417

×
UNCOV
418
        witness, err := i.createWitness(
×
UNCOV
419
                signer, txn, hashCache, prevOutputFetcher, txinIdx,
×
UNCOV
420
        )
×
UNCOV
421
        if err != nil {
×
422
                return nil, err
×
423
        }
×
424

UNCOV
425
        return &Script{
×
UNCOV
426
                Witness: witness,
×
UNCOV
427
        }, nil
×
428
}
429

430
// MakeHtlcSecondLevelTimeoutAnchorInput creates an input allowing the sweeper
431
// to spend the HTLC output on our commit using the second level timeout
432
// transaction.
433
func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx,
434
        signDetails *SignDetails, heightHint uint32,
435
        opts ...InputOpt) HtlcSecondLevelAnchorInput {
2✔
436

2✔
437
        // Spend an HTLC output on our local commitment tx using the
2✔
438
        // 2nd timeout transaction.
2✔
439
        createWitness := func(signer Signer, txn *wire.MsgTx,
2✔
440
                hashCache *txscript.TxSigHashes,
2✔
441
                prevOutputFetcher txscript.PrevOutputFetcher,
2✔
442
                txinIdx int) (wire.TxWitness, error) {
2✔
UNCOV
443

×
UNCOV
444
                desc := signDetails.SignDesc
×
UNCOV
445
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
446
                desc.InputIndex = txinIdx
×
UNCOV
447
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
448

×
UNCOV
449
                return SenderHtlcSpendTimeout(
×
UNCOV
450
                        signDetails.PeerSig, signDetails.SigHashType, signer,
×
UNCOV
451
                        &desc, txn,
×
UNCOV
452
                )
×
UNCOV
453
        }
×
454

455
        input := MakeBaseInput(
2✔
456
                &signedTx.TxIn[0].PreviousOutPoint,
2✔
457
                HtlcOfferedTimeoutSecondLevelInputConfirmed,
2✔
458
                &signDetails.SignDesc, heightHint, nil, opts...,
2✔
459
        )
2✔
460
        input.blockToMaturity = 1
2✔
461

2✔
462
        return HtlcSecondLevelAnchorInput{
2✔
463
                inputKit:      input.inputKit,
2✔
464
                SignedTx:      signedTx,
2✔
465
                createWitness: createWitness,
2✔
466
        }
2✔
467
}
468

469
// MakeHtlcSecondLevelTimeoutTaprootInput creates an input that allows the
470
// sweeper to spend an HTLC output to the second level on our commitment
471
// transaction. The sweeper is also able to generate witnesses on demand to
472
// sweep the second level HTLC aggregated with other transactions.
473
func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx,
474
        signDetails *SignDetails,
UNCOV
475
        heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
×
UNCOV
476

×
UNCOV
477
        createWitness := func(signer Signer, txn *wire.MsgTx,
×
UNCOV
478
                hashCache *txscript.TxSigHashes,
×
UNCOV
479
                prevOutputFetcher txscript.PrevOutputFetcher,
×
UNCOV
480
                txinIdx int) (wire.TxWitness, error) {
×
UNCOV
481

×
UNCOV
482
                desc := signDetails.SignDesc
×
UNCOV
483
                if desc.ControlBlock == nil {
×
484
                        return nil, fmt.Errorf("ctrl block must be set")
×
485
                }
×
486

UNCOV
487
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
488
                desc.InputIndex = txinIdx
×
UNCOV
489
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
490

×
UNCOV
491
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
492

×
UNCOV
493
                return SenderHTLCScriptTaprootTimeout(
×
UNCOV
494
                        signDetails.PeerSig, signDetails.SigHashType, signer,
×
UNCOV
495
                        &desc, txn, nil, nil,
×
UNCOV
496
                )
×
497
        }
498

UNCOV
499
        input := MakeBaseInput(
×
UNCOV
500
                &signedTx.TxIn[0].PreviousOutPoint,
×
UNCOV
501
                TaprootHtlcLocalOfferedTimeout,
×
UNCOV
502
                &signDetails.SignDesc, heightHint, nil, opts...,
×
UNCOV
503
        )
×
UNCOV
504
        input.blockToMaturity = 1
×
UNCOV
505

×
UNCOV
506
        return HtlcSecondLevelAnchorInput{
×
UNCOV
507
                inputKit:      input.inputKit,
×
UNCOV
508
                SignedTx:      signedTx,
×
UNCOV
509
                createWitness: createWitness,
×
UNCOV
510
        }
×
511
}
512

513
// MakeHtlcSecondLevelSuccessAnchorInput creates an input allowing the sweeper
514
// to spend the HTLC output on our commit using the second level success
515
// transaction.
516
func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx,
517
        signDetails *SignDetails, preimage lntypes.Preimage,
518
        heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
1✔
519

1✔
520
        // Spend an HTLC output on our local commitment tx using the 2nd
1✔
521
        // success transaction.
1✔
522
        createWitness := func(signer Signer, txn *wire.MsgTx,
1✔
523
                hashCache *txscript.TxSigHashes,
1✔
524
                prevOutputFetcher txscript.PrevOutputFetcher,
1✔
525
                txinIdx int) (wire.TxWitness, error) {
1✔
UNCOV
526

×
UNCOV
527
                desc := signDetails.SignDesc
×
UNCOV
528
                desc.SigHashes = hashCache
×
UNCOV
529
                desc.InputIndex = txinIdx
×
UNCOV
530
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
531

×
UNCOV
532
                return ReceiverHtlcSpendRedeem(
×
UNCOV
533
                        signDetails.PeerSig, signDetails.SigHashType,
×
UNCOV
534
                        preimage[:], signer, &desc, txn,
×
UNCOV
535
                )
×
UNCOV
536
        }
×
537
        input := MakeBaseInput(
1✔
538
                &signedTx.TxIn[0].PreviousOutPoint,
1✔
539
                HtlcAcceptedSuccessSecondLevelInputConfirmed,
1✔
540
                &signDetails.SignDesc, heightHint, nil, opts...,
1✔
541
        )
1✔
542
        input.blockToMaturity = 1
1✔
543

1✔
544
        return HtlcSecondLevelAnchorInput{
1✔
545
                SignedTx:      signedTx,
1✔
546
                inputKit:      input.inputKit,
1✔
547
                createWitness: createWitness,
1✔
548
        }
1✔
549
}
550

551
// MakeHtlcSecondLevelSuccessTaprootInput creates an input that allows the
552
// sweeper to spend an HTLC output to the second level on our taproot
553
// commitment transaction.
554
func MakeHtlcSecondLevelSuccessTaprootInput(signedTx *wire.MsgTx,
555
        signDetails *SignDetails, preimage lntypes.Preimage,
UNCOV
556
        heightHint uint32, opts ...InputOpt) HtlcSecondLevelAnchorInput {
×
UNCOV
557

×
UNCOV
558
        createWitness := func(signer Signer, txn *wire.MsgTx,
×
UNCOV
559
                hashCache *txscript.TxSigHashes,
×
UNCOV
560
                prevOutputFetcher txscript.PrevOutputFetcher,
×
UNCOV
561
                txinIdx int) (wire.TxWitness, error) {
×
UNCOV
562

×
UNCOV
563
                desc := signDetails.SignDesc
×
UNCOV
564
                if desc.ControlBlock == nil {
×
565
                        return nil, fmt.Errorf("ctrl block must be set")
×
566
                }
×
567

UNCOV
568
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
569
                desc.InputIndex = txinIdx
×
UNCOV
570
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
571

×
UNCOV
572
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
573

×
UNCOV
574
                return ReceiverHTLCScriptTaprootRedeem(
×
UNCOV
575
                        signDetails.PeerSig, signDetails.SigHashType,
×
UNCOV
576
                        preimage[:], signer, &desc, txn, nil, nil,
×
UNCOV
577
                )
×
578
        }
579

UNCOV
580
        input := MakeBaseInput(
×
UNCOV
581
                &signedTx.TxIn[0].PreviousOutPoint,
×
UNCOV
582
                TaprootHtlcAcceptedLocalSuccess,
×
UNCOV
583
                &signDetails.SignDesc, heightHint, nil, opts...,
×
UNCOV
584
        )
×
UNCOV
585
        input.blockToMaturity = 1
×
UNCOV
586

×
UNCOV
587
        return HtlcSecondLevelAnchorInput{
×
UNCOV
588
                inputKit:      input.inputKit,
×
UNCOV
589
                SignedTx:      signedTx,
×
UNCOV
590
                createWitness: createWitness,
×
UNCOV
591
        }
×
592
}
593

594
// Compile-time constraints to ensure each input struct implement the Input
595
// interface.
596
var _ Input = (*BaseInput)(nil)
597
var _ Input = (*HtlcSucceedInput)(nil)
598
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