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

lightningnetwork / lnd / 10285980579

07 Aug 2024 02:11PM UTC coverage: 57.666% (-0.8%) from 58.478%
10285980579

push

github

web-flow
Merge pull request #8886 from bitromortac/buildroute-inbound-fees

routing: inbound fees support for BuildRoute

311 of 321 new or added lines in 1 file covered. (96.88%)

18350 existing lines in 229 files now uncovered.

94516 of 163902 relevant lines covered (57.67%)

37110.62 hits per line

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

40.14
/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/lntypes"
10
)
11

12
// EmptyOutPoint is a zeroed outpoint.
13
var EmptyOutPoint wire.OutPoint
14

15
// Input represents an abstract UTXO which is to be spent using a sweeping
16
// transaction. The method provided give the caller all information needed to
17
// construct a valid input within a sweeping transaction to sweep this
18
// lingering UTXO.
19
type Input interface {
20
        // Outpoint returns the reference to the output being spent, used to
21
        // construct the corresponding transaction input.
22
        OutPoint() wire.OutPoint
23

24
        // RequiredTxOut returns a non-nil TxOut if input commits to a certain
25
        // transaction output. This is used in the SINGLE|ANYONECANPAY case to
26
        // make sure any presigned input is still valid by including the
27
        // output.
28
        RequiredTxOut() *wire.TxOut
29

30
        // RequiredLockTime returns whether this input commits to a tx locktime
31
        // that must be used in the transaction including it.
32
        RequiredLockTime() (uint32, bool)
33

34
        // WitnessType returns an enum specifying the type of witness that must
35
        // be generated in order to spend this output.
36
        WitnessType() WitnessType
37

38
        // SignDesc returns a reference to a spendable output's sign
39
        // descriptor, which is used during signing to compute a valid witness
40
        // that spends this output.
41
        SignDesc() *SignDescriptor
42

43
        // CraftInputScript returns a valid set of input scripts allowing this
44
        // output to be spent. The returns input scripts should target the
45
        // input at location txIndex within the passed transaction. The input
46
        // scripts generated by this method support spending p2wkh, p2wsh, and
47
        // also nested p2sh outputs.
48
        CraftInputScript(signer Signer, txn *wire.MsgTx,
49
                hashCache *txscript.TxSigHashes,
50
                prevOutputFetcher txscript.PrevOutputFetcher,
51
                txinIdx int) (*Script, error)
52

53
        // BlocksToMaturity returns the relative timelock, as a number of
54
        // blocks, that must be built on top of the confirmation height before
55
        // the output can be spent. For non-CSV locked inputs this is always
56
        // zero.
57
        BlocksToMaturity() uint32
58

59
        // HeightHint returns the minimum height at which a confirmed spending
60
        // tx can occur.
61
        HeightHint() uint32
62

63
        // UnconfParent returns information about a possibly unconfirmed parent
64
        // tx.
65
        UnconfParent() *TxInfo
66
}
67

68
// TxInfo describes properties of a parent tx that are relevant for CPFP.
69
type TxInfo struct {
70
        // Fee is the fee of the tx.
71
        Fee btcutil.Amount
72

73
        // Weight is the weight of the tx.
74
        Weight lntypes.WeightUnit
75
}
76

77
// String returns a human readable version of the tx info.
UNCOV
78
func (t *TxInfo) String() string {
×
UNCOV
79
        return fmt.Sprintf("fee=%v, weight=%v", t.Fee, t.Weight)
×
UNCOV
80
}
×
81

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

91
        // PeerSig is the peer's signature for this input.
92
        PeerSig Signature
93

94
        // SigHashType is the sighash signed by the peer.
95
        SigHashType txscript.SigHashType
96
}
97

98
type inputKit struct {
99
        outpoint        wire.OutPoint
100
        witnessType     WitnessType
101
        signDesc        SignDescriptor
102
        heightHint      uint32
103
        blockToMaturity uint32
104
        cltvExpiry      uint32
105

106
        // unconfParent contains information about a potential unconfirmed
107
        // parent transaction.
108
        unconfParent *TxInfo
109
}
110

111
// OutPoint returns the breached output's identifier that is to be included as
112
// a transaction input.
113
func (i *inputKit) OutPoint() wire.OutPoint {
2,911✔
114
        return i.outpoint
2,911✔
115
}
2,911✔
116

117
// RequiredTxOut returns a nil for the base input type.
118
func (i *inputKit) RequiredTxOut() *wire.TxOut {
131✔
119
        return nil
131✔
120
}
131✔
121

122
// RequiredLockTime returns whether this input commits to a tx locktime that
123
// must be used in the transaction including it. This will be false for the
124
// base input type since we can re-sign for any lock time.
125
func (i *inputKit) RequiredLockTime() (uint32, bool) {
24✔
126
        return i.cltvExpiry, i.cltvExpiry > 0
24✔
127
}
24✔
128

129
// WitnessType returns the type of witness that must be generated to spend the
130
// breached output.
131
func (i *inputKit) WitnessType() WitnessType {
1,519✔
132
        return i.witnessType
1,519✔
133
}
1,519✔
134

135
// SignDesc returns the breached output's SignDescriptor, which is used during
136
// signing to compute the witness.
137
func (i *inputKit) SignDesc() *SignDescriptor {
2,871✔
138
        return &i.signDesc
2,871✔
139
}
2,871✔
140

141
// HeightHint returns the minimum height at which a confirmed spending
142
// tx can occur.
UNCOV
143
func (i *inputKit) HeightHint() uint32 {
×
UNCOV
144
        return i.heightHint
×
UNCOV
145
}
×
146

147
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
148
// must be built on top of the confirmation height before the output can be
149
// spent. For non-CSV locked inputs this is always zero.
150
func (i *inputKit) BlocksToMaturity() uint32 {
1,415✔
151
        return i.blockToMaturity
1,415✔
152
}
1,415✔
153

154
// Cpfp returns information about a possibly unconfirmed parent tx.
155
func (i *inputKit) UnconfParent() *TxInfo {
61✔
156
        return i.unconfParent
61✔
157
}
61✔
158

159
// BaseInput contains all the information needed to sweep a basic
160
// output (CSV/CLTV/no time lock).
161
type BaseInput struct {
162
        inputKit
163
}
164

165
// MakeBaseInput assembles a new BaseInput that can be used to construct a
166
// sweep transaction.
167
func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
168
        signDescriptor *SignDescriptor, heightHint uint32,
169
        unconfParent *TxInfo) BaseInput {
602✔
170

602✔
171
        return BaseInput{
602✔
172
                inputKit{
602✔
173
                        outpoint:     *outpoint,
602✔
174
                        witnessType:  witnessType,
602✔
175
                        signDesc:     *signDescriptor,
602✔
176
                        heightHint:   heightHint,
602✔
177
                        unconfParent: unconfParent,
602✔
178
                },
602✔
179
        }
602✔
180
}
602✔
181

182
// NewBaseInput allocates and assembles a new *BaseInput that can be used to
183
// construct a sweep transaction.
184
func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
185
        signDescriptor *SignDescriptor, heightHint uint32) *BaseInput {
566✔
186

566✔
187
        input := MakeBaseInput(
566✔
188
                outpoint, witnessType, signDescriptor, heightHint, nil,
566✔
189
        )
566✔
190

566✔
191
        return &input
566✔
192
}
566✔
193

194
// NewCsvInput assembles a new csv-locked input that can be used to
195
// construct a sweep transaction.
196
func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType,
197
        signDescriptor *SignDescriptor, heightHint uint32,
198
        blockToMaturity uint32) *BaseInput {
509✔
199

509✔
200
        return &BaseInput{
509✔
201
                inputKit{
509✔
202
                        outpoint:        *outpoint,
509✔
203
                        witnessType:     witnessType,
509✔
204
                        signDesc:        *signDescriptor,
509✔
205
                        heightHint:      heightHint,
509✔
206
                        blockToMaturity: blockToMaturity,
509✔
207
                },
509✔
208
        }
509✔
209
}
509✔
210

211
// NewCsvInputWithCltv assembles a new csv and cltv locked input that can be
212
// used to construct a sweep transaction.
213
func NewCsvInputWithCltv(outpoint *wire.OutPoint, witnessType WitnessType,
214
        signDescriptor *SignDescriptor, heightHint uint32,
UNCOV
215
        csvDelay uint32, cltvExpiry uint32) *BaseInput {
×
UNCOV
216

×
UNCOV
217
        return &BaseInput{
×
UNCOV
218
                inputKit{
×
UNCOV
219
                        outpoint:        *outpoint,
×
UNCOV
220
                        witnessType:     witnessType,
×
UNCOV
221
                        signDesc:        *signDescriptor,
×
UNCOV
222
                        heightHint:      heightHint,
×
UNCOV
223
                        blockToMaturity: csvDelay,
×
UNCOV
224
                        cltvExpiry:      cltvExpiry,
×
UNCOV
225
                        unconfParent:    nil,
×
UNCOV
226
                },
×
UNCOV
227
        }
×
UNCOV
228
}
×
229

230
// CraftInputScript returns a valid set of input scripts allowing this output
231
// to be spent. The returned input scripts should target the input at location
232
// txIndex within the passed transaction. The input scripts generated by this
233
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
234
func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
235
        hashCache *txscript.TxSigHashes,
236
        prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script,
237
        error) {
1,415✔
238

1,415✔
239
        signDesc := bi.SignDesc()
1,415✔
240
        signDesc.PrevOutputFetcher = prevOutputFetcher
1,415✔
241
        witnessFunc := bi.witnessType.WitnessGenerator(signer, signDesc)
1,415✔
242

1,415✔
243
        return witnessFunc(txn, hashCache, txinIdx)
1,415✔
244
}
1,415✔
245

246
// HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input
247
// is expected to reside on the commitment tx of the remote party and should
248
// not be a second level tx output.
249
type HtlcSucceedInput struct {
250
        inputKit
251

252
        preimage []byte
253
}
254

255
// MakeHtlcSucceedInput assembles a new redeem input that can be used to
256
// construct a sweep transaction.
257
func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
258
        signDescriptor *SignDescriptor, preimage []byte, heightHint,
259
        blocksToMaturity uint32) HtlcSucceedInput {
1✔
260

1✔
261
        return HtlcSucceedInput{
1✔
262
                inputKit: inputKit{
1✔
263
                        outpoint:        *outpoint,
1✔
264
                        witnessType:     HtlcAcceptedRemoteSuccess,
1✔
265
                        signDesc:        *signDescriptor,
1✔
266
                        heightHint:      heightHint,
1✔
267
                        blockToMaturity: blocksToMaturity,
1✔
268
                },
1✔
269
                preimage: preimage,
1✔
270
        }
1✔
271
}
1✔
272

273
// MakeTaprootHtlcSucceedInput creates a new HtlcSucceedInput that can be used
274
// to spend an HTLC output for a taproot channel on the remote party's
275
// commitment transaction.
276
func MakeTaprootHtlcSucceedInput(op *wire.OutPoint, signDesc *SignDescriptor,
UNCOV
277
        preimage []byte, heightHint, blocksToMaturity uint32) HtlcSucceedInput {
×
UNCOV
278

×
UNCOV
279
        return HtlcSucceedInput{
×
UNCOV
280
                inputKit: inputKit{
×
UNCOV
281
                        outpoint:        *op,
×
UNCOV
282
                        witnessType:     TaprootHtlcAcceptedRemoteSuccess,
×
UNCOV
283
                        signDesc:        *signDesc,
×
UNCOV
284
                        heightHint:      heightHint,
×
UNCOV
285
                        blockToMaturity: blocksToMaturity,
×
UNCOV
286
                },
×
UNCOV
287
                preimage: preimage,
×
UNCOV
288
        }
×
UNCOV
289
}
×
290

291
// CraftInputScript returns a valid set of input scripts allowing this output
292
// to be spent. The returns input scripts should target the input at location
293
// txIndex within the passed transaction. The input scripts generated by this
294
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
295
func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
296
        hashCache *txscript.TxSigHashes,
297
        prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script,
UNCOV
298
        error) {
×
UNCOV
299

×
UNCOV
300
        desc := h.signDesc
×
UNCOV
301
        desc.SigHashes = hashCache
×
UNCOV
302
        desc.InputIndex = txinIdx
×
UNCOV
303
        desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
304

×
UNCOV
305
        isTaproot := txscript.IsPayToTaproot(desc.Output.PkScript)
×
UNCOV
306

×
UNCOV
307
        var (
×
UNCOV
308
                witness wire.TxWitness
×
UNCOV
309
                err     error
×
UNCOV
310
        )
×
UNCOV
311
        if isTaproot {
×
UNCOV
312
                if desc.ControlBlock == nil {
×
313
                        return nil, fmt.Errorf("ctrl block must be set")
×
314
                }
×
315

UNCOV
316
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
317

×
UNCOV
318
                witness, err = SenderHTLCScriptTaprootRedeem(
×
UNCOV
319
                        signer, &desc, txn, h.preimage, nil, nil,
×
UNCOV
320
                )
×
UNCOV
321
        } else {
×
UNCOV
322
                witness, err = SenderHtlcSpendRedeem(
×
UNCOV
323
                        signer, &desc, txn, h.preimage,
×
UNCOV
324
                )
×
UNCOV
325
        }
×
UNCOV
326
        if err != nil {
×
327
                return nil, err
×
328
        }
×
329

UNCOV
330
        return &Script{
×
UNCOV
331
                Witness: witness,
×
UNCOV
332
        }, nil
×
333
}
334

335
// HtlcSecondLevelAnchorInput is an input type used to spend HTLC outputs
336
// using a re-signed second level transaction, either via the timeout or success
337
// paths.
338
type HtlcSecondLevelAnchorInput struct {
339
        inputKit
340

341
        // SignedTx is the original second level transaction signed by the
342
        // channel peer.
343
        SignedTx *wire.MsgTx
344

345
        // createWitness creates a witness allowing the passed transaction to
346
        // spend the input.
347
        createWitness func(signer Signer, txn *wire.MsgTx,
348
                hashCache *txscript.TxSigHashes,
349
                prevOutputFetcher txscript.PrevOutputFetcher,
350
                txinIdx int) (wire.TxWitness, error)
351
}
352

353
// RequiredTxOut returns the tx out needed to be present on the sweep tx for
354
// the spend of the input to be valid.
UNCOV
355
func (i *HtlcSecondLevelAnchorInput) RequiredTxOut() *wire.TxOut {
×
UNCOV
356
        return i.SignedTx.TxOut[0]
×
UNCOV
357
}
×
358

359
// RequiredLockTime returns the locktime needed for the sweep tx for the spend
360
// of the input to be valid. For a second level HTLC timeout this will be the
361
// CLTV expiry, for HTLC success it will be zero.
UNCOV
362
func (i *HtlcSecondLevelAnchorInput) RequiredLockTime() (uint32, bool) {
×
UNCOV
363
        return i.SignedTx.LockTime, true
×
UNCOV
364
}
×
365

366
// CraftInputScript returns a valid set of input scripts allowing this output
367
// to be spent. The returns input scripts should target the input at location
368
// txIndex within the passed transaction. The input scripts generated by this
369
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
370
func (i *HtlcSecondLevelAnchorInput) CraftInputScript(signer Signer,
371
        txn *wire.MsgTx, hashCache *txscript.TxSigHashes,
372
        prevOutputFetcher txscript.PrevOutputFetcher, txinIdx int) (*Script,
UNCOV
373
        error) {
×
UNCOV
374

×
UNCOV
375
        witness, err := i.createWitness(
×
UNCOV
376
                signer, txn, hashCache, prevOutputFetcher, txinIdx,
×
UNCOV
377
        )
×
UNCOV
378
        if err != nil {
×
379
                return nil, err
×
380
        }
×
381

UNCOV
382
        return &Script{
×
UNCOV
383
                Witness: witness,
×
UNCOV
384
        }, nil
×
385
}
386

387
// MakeHtlcSecondLevelTimeoutAnchorInput creates an input allowing the sweeper
388
// to spend the HTLC output on our commit using the second level timeout
389
// transaction.
390
func MakeHtlcSecondLevelTimeoutAnchorInput(signedTx *wire.MsgTx,
391
        signDetails *SignDetails, heightHint uint32) HtlcSecondLevelAnchorInput {
2✔
392

2✔
393
        // Spend an HTLC output on our local commitment tx using the
2✔
394
        // 2nd timeout transaction.
2✔
395
        createWitness := func(signer Signer, txn *wire.MsgTx,
2✔
396
                hashCache *txscript.TxSigHashes,
2✔
397
                prevOutputFetcher txscript.PrevOutputFetcher,
2✔
398
                txinIdx int) (wire.TxWitness, error) {
2✔
UNCOV
399

×
UNCOV
400
                desc := signDetails.SignDesc
×
UNCOV
401
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
402
                desc.InputIndex = txinIdx
×
UNCOV
403
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
404

×
UNCOV
405
                return SenderHtlcSpendTimeout(
×
UNCOV
406
                        signDetails.PeerSig, signDetails.SigHashType, signer,
×
UNCOV
407
                        &desc, txn,
×
UNCOV
408
                )
×
UNCOV
409
        }
×
410

411
        return HtlcSecondLevelAnchorInput{
2✔
412
                inputKit: inputKit{
2✔
413
                        outpoint:    signedTx.TxIn[0].PreviousOutPoint,
2✔
414
                        witnessType: HtlcOfferedTimeoutSecondLevelInputConfirmed,
2✔
415
                        signDesc:    signDetails.SignDesc,
2✔
416
                        heightHint:  heightHint,
2✔
417

2✔
418
                        // CSV delay is always 1 for these inputs.
2✔
419
                        blockToMaturity: 1,
2✔
420
                },
2✔
421
                SignedTx:      signedTx,
2✔
422
                createWitness: createWitness,
2✔
423
        }
2✔
424
}
425

426
// MakeHtlcSecondLevelTimeoutTaprootInput creates an input that allows the
427
// sweeper to spend an HTLC output to the second level on our commitment
428
// transaction. The sweeper is also able to generate witnesses on demand to
429
// sweep the second level HTLC aggregated with other transactions.
430
func MakeHtlcSecondLevelTimeoutTaprootInput(signedTx *wire.MsgTx,
431
        signDetails *SignDetails,
UNCOV
432
        heightHint uint32) HtlcSecondLevelAnchorInput {
×
UNCOV
433

×
UNCOV
434
        createWitness := func(signer Signer, txn *wire.MsgTx,
×
UNCOV
435
                hashCache *txscript.TxSigHashes,
×
UNCOV
436
                prevOutputFetcher txscript.PrevOutputFetcher,
×
UNCOV
437
                txinIdx int) (wire.TxWitness, error) {
×
UNCOV
438

×
UNCOV
439
                desc := signDetails.SignDesc
×
UNCOV
440
                if desc.ControlBlock == nil {
×
441
                        return nil, fmt.Errorf("ctrl block must be set")
×
442
                }
×
443

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

×
UNCOV
448
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
449

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

UNCOV
456
        return HtlcSecondLevelAnchorInput{
×
UNCOV
457
                inputKit: inputKit{
×
UNCOV
458
                        outpoint:    signedTx.TxIn[0].PreviousOutPoint,
×
UNCOV
459
                        witnessType: TaprootHtlcLocalOfferedTimeout,
×
UNCOV
460
                        signDesc:    signDetails.SignDesc,
×
UNCOV
461
                        heightHint:  heightHint,
×
UNCOV
462

×
UNCOV
463
                        // CSV delay is always 1 for these inputs.
×
UNCOV
464
                        blockToMaturity: 1,
×
UNCOV
465
                },
×
UNCOV
466
                SignedTx:      signedTx,
×
UNCOV
467
                createWitness: createWitness,
×
UNCOV
468
        }
×
469
}
470

471
// MakeHtlcSecondLevelSuccessAnchorInput creates an input allowing the sweeper
472
// to spend the HTLC output on our commit using the second level success
473
// transaction.
474
func MakeHtlcSecondLevelSuccessAnchorInput(signedTx *wire.MsgTx,
475
        signDetails *SignDetails, preimage lntypes.Preimage,
476
        heightHint uint32) HtlcSecondLevelAnchorInput {
1✔
477

1✔
478
        // Spend an HTLC output on our local commitment tx using the 2nd
1✔
479
        // success transaction.
1✔
480
        createWitness := func(signer Signer, txn *wire.MsgTx,
1✔
481
                hashCache *txscript.TxSigHashes,
1✔
482
                prevOutputFetcher txscript.PrevOutputFetcher,
1✔
483
                txinIdx int) (wire.TxWitness, error) {
1✔
UNCOV
484

×
UNCOV
485
                desc := signDetails.SignDesc
×
UNCOV
486
                desc.SigHashes = hashCache
×
UNCOV
487
                desc.InputIndex = txinIdx
×
UNCOV
488
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
489

×
UNCOV
490
                return ReceiverHtlcSpendRedeem(
×
UNCOV
491
                        signDetails.PeerSig, signDetails.SigHashType,
×
UNCOV
492
                        preimage[:], signer, &desc, txn,
×
UNCOV
493
                )
×
UNCOV
494
        }
×
495

496
        return HtlcSecondLevelAnchorInput{
1✔
497
                inputKit: inputKit{
1✔
498
                        outpoint:    signedTx.TxIn[0].PreviousOutPoint,
1✔
499
                        witnessType: HtlcAcceptedSuccessSecondLevelInputConfirmed,
1✔
500
                        signDesc:    signDetails.SignDesc,
1✔
501
                        heightHint:  heightHint,
1✔
502

1✔
503
                        // CSV delay is always 1 for these inputs.
1✔
504
                        blockToMaturity: 1,
1✔
505
                },
1✔
506
                SignedTx:      signedTx,
1✔
507
                createWitness: createWitness,
1✔
508
        }
1✔
509
}
510

511
// MakeHtlcSecondLevelSuccessTaprootInput creates an input that allows the
512
// sweeper to spend an HTLC output to the second level on our taproot
513
// commitment transaction.
514
func MakeHtlcSecondLevelSuccessTaprootInput(signedTx *wire.MsgTx,
515
        signDetails *SignDetails, preimage lntypes.Preimage,
UNCOV
516
        heightHint uint32) HtlcSecondLevelAnchorInput {
×
UNCOV
517

×
UNCOV
518
        createWitness := func(signer Signer, txn *wire.MsgTx,
×
UNCOV
519
                hashCache *txscript.TxSigHashes,
×
UNCOV
520
                prevOutputFetcher txscript.PrevOutputFetcher,
×
UNCOV
521
                txinIdx int) (wire.TxWitness, error) {
×
UNCOV
522

×
UNCOV
523
                desc := signDetails.SignDesc
×
UNCOV
524
                if desc.ControlBlock == nil {
×
525
                        return nil, fmt.Errorf("ctrl block must be set")
×
526
                }
×
527

UNCOV
528
                desc.SigHashes = txscript.NewTxSigHashes(txn, prevOutputFetcher)
×
UNCOV
529
                desc.InputIndex = txinIdx
×
UNCOV
530
                desc.PrevOutputFetcher = prevOutputFetcher
×
UNCOV
531

×
UNCOV
532
                desc.SignMethod = TaprootScriptSpendSignMethod
×
UNCOV
533

×
UNCOV
534
                return ReceiverHTLCScriptTaprootRedeem(
×
UNCOV
535
                        signDetails.PeerSig, signDetails.SigHashType,
×
UNCOV
536
                        preimage[:], signer, &desc, txn, nil, nil,
×
UNCOV
537
                )
×
538
        }
539

UNCOV
540
        return HtlcSecondLevelAnchorInput{
×
UNCOV
541
                inputKit: inputKit{
×
UNCOV
542
                        outpoint:    signedTx.TxIn[0].PreviousOutPoint,
×
UNCOV
543
                        witnessType: TaprootHtlcAcceptedLocalSuccess,
×
UNCOV
544
                        signDesc:    signDetails.SignDesc,
×
UNCOV
545
                        heightHint:  heightHint,
×
UNCOV
546

×
UNCOV
547
                        // CSV delay is always 1 for these inputs.
×
UNCOV
548
                        blockToMaturity: 1,
×
UNCOV
549
                },
×
UNCOV
550
                SignedTx:      signedTx,
×
UNCOV
551
                createWitness: createWitness,
×
UNCOV
552
        }
×
553
}
554

555
// Compile-time constraints to ensure each input struct implement the Input
556
// interface.
557
var _ Input = (*BaseInput)(nil)
558
var _ Input = (*HtlcSucceedInput)(nil)
559
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

© 2026 Coveralls, Inc