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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

90.22
/input/taproot.go
1
package input
2

3
import (
4
        "fmt"
5

6
        "github.com/btcsuite/btcd/btcec/v2"
7
        "github.com/btcsuite/btcd/btcec/v2/schnorr"
8
        "github.com/btcsuite/btcd/txscript"
9
        "github.com/btcsuite/btcd/wire"
10
        "github.com/btcsuite/btcwallet/waddrmgr"
11
        "github.com/lightningnetwork/lnd/fn/v2"
12
)
13

14
const (
15
        // PubKeyFormatCompressedOdd is the identifier prefix byte for a public
16
        // key whose Y coordinate is odd when serialized in the compressed
17
        // format per section 2.3.4 of
18
        // [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4).
19
        // This is copied from the github.com/decred/dcrd/dcrec/secp256k1/v4 to
20
        // avoid needing to directly reference (and by accident pull in
21
        // incompatible crypto primitives) the package.
22
        PubKeyFormatCompressedOdd byte = 0x03
23
)
24

25
// AuxTapLeaf is a type alias for an optional tapscript leaf that may be added
26
// to the tapscript tree of HTLC and commitment outputs.
27
type AuxTapLeaf = fn.Option[txscript.TapLeaf]
28

29
// NoneTapLeaf returns an empty optional tapscript leaf.
UNCOV
30
func NoneTapLeaf() AuxTapLeaf {
×
UNCOV
31
        return fn.None[txscript.TapLeaf]()
×
UNCOV
32
}
×
33

34
// HtlcIndex represents the monotonically increasing counter that is used to
35
// identify HTLCs created by a peer.
36
type HtlcIndex = uint64
37

38
// HtlcAuxLeaf is a type that represents an auxiliary leaf for an HTLC output.
39
// An HTLC may have up to two aux leaves: one for the output on the commitment
40
// transaction, and one for the second level HTLC.
41
type HtlcAuxLeaf struct {
42
        AuxTapLeaf
43

44
        // SecondLevelLeaf is the auxiliary leaf for the second level HTLC
45
        // success or timeout transaction.
46
        SecondLevelLeaf AuxTapLeaf
47
}
48

49
// HtlcAuxLeaves is a type alias for a map of optional tapscript leaves.
50
type HtlcAuxLeaves = map[HtlcIndex]HtlcAuxLeaf
51

52
// NewTxSigHashesV0Only returns a new txscript.TxSigHashes instance that will
53
// only calculate the sighash midstate values for segwit v0 inputs and can
54
// therefore never be used for transactions that want to spend segwit v1
55
// (taproot) inputs.
56
func NewTxSigHashesV0Only(tx *wire.MsgTx) *txscript.TxSigHashes {
3✔
57
        // The canned output fetcher returns a wire.TxOut instance with the
3✔
58
        // given pk script and amount. We can get away with nil since the first
3✔
59
        // thing the TxSigHashes constructor checks is the length of the pk
3✔
60
        // script and whether it matches taproot output script length. If the
3✔
61
        // length doesn't match it assumes v0 inputs only.
3✔
62
        nilFetcher := txscript.NewCannedPrevOutputFetcher(nil, 0)
3✔
63
        return txscript.NewTxSigHashes(tx, nilFetcher)
3✔
64
}
3✔
65

66
// MultiPrevOutFetcher returns a txscript.MultiPrevOutFetcher for the given set
67
// of inputs.
68
func MultiPrevOutFetcher(inputs []Input) (*txscript.MultiPrevOutFetcher, error) {
3✔
69
        fetcher := txscript.NewMultiPrevOutFetcher(nil)
3✔
70
        for _, inp := range inputs {
6✔
71
                op := inp.OutPoint()
3✔
72
                desc := inp.SignDesc()
3✔
73

3✔
74
                if op == EmptyOutPoint {
3✔
75
                        return nil, fmt.Errorf("missing input outpoint")
×
76
                }
×
77

78
                if desc == nil || desc.Output == nil {
3✔
79
                        return nil, fmt.Errorf("missing input utxo information")
×
80
                }
×
81

82
                fetcher.AddPrevOut(op, desc.Output)
3✔
83
        }
84

85
        return fetcher, nil
3✔
86
}
87

88
// TapscriptFullTree creates a waddrmgr.Tapscript for the given internal key and
89
// tree leaves.
90
func TapscriptFullTree(internalKey *btcec.PublicKey,
91
        allTreeLeaves ...txscript.TapLeaf) *waddrmgr.Tapscript {
3✔
92

3✔
93
        tree := txscript.AssembleTaprootScriptTree(allTreeLeaves...)
3✔
94
        rootHash := tree.RootNode.TapHash()
3✔
95
        tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
3✔
96

3✔
97
        var outputKeyYIsOdd bool
3✔
98
        if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
5✔
99
                outputKeyYIsOdd = true
2✔
100
        }
2✔
101

102
        return &waddrmgr.Tapscript{
3✔
103
                Type: waddrmgr.TapscriptTypeFullTree,
3✔
104
                ControlBlock: &txscript.ControlBlock{
3✔
105
                        InternalKey:     internalKey,
3✔
106
                        OutputKeyYIsOdd: outputKeyYIsOdd,
3✔
107
                        LeafVersion:     txscript.BaseLeafVersion,
3✔
108
                },
3✔
109
                Leaves: allTreeLeaves,
3✔
110
        }
3✔
111
}
112

113
// TapscriptPartialReveal creates a waddrmgr.Tapscript for the given internal
114
// key and revealed script.
115
func TapscriptPartialReveal(internalKey *btcec.PublicKey,
116
        revealedLeaf txscript.TapLeaf,
117
        inclusionProof []byte) *waddrmgr.Tapscript {
3✔
118

3✔
119
        controlBlock := &txscript.ControlBlock{
3✔
120
                InternalKey:    internalKey,
3✔
121
                LeafVersion:    txscript.BaseLeafVersion,
3✔
122
                InclusionProof: inclusionProof,
3✔
123
        }
3✔
124
        rootHash := controlBlock.RootHash(revealedLeaf.Script)
3✔
125
        tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash)
3✔
126

3✔
127
        if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
3✔
UNCOV
128
                controlBlock.OutputKeyYIsOdd = true
×
UNCOV
129
        }
×
130

131
        return &waddrmgr.Tapscript{
3✔
132
                Type:           waddrmgr.TapscriptTypePartialReveal,
3✔
133
                ControlBlock:   controlBlock,
3✔
134
                RevealedScript: revealedLeaf.Script,
3✔
135
        }
3✔
136
}
137

138
// TapscriptRootHashOnly creates a waddrmgr.Tapscript for the given internal key
139
// and root hash.
140
func TapscriptRootHashOnly(internalKey *btcec.PublicKey,
141
        rootHash []byte) *waddrmgr.Tapscript {
3✔
142

3✔
143
        controlBlock := &txscript.ControlBlock{
3✔
144
                InternalKey: internalKey,
3✔
145
        }
3✔
146

3✔
147
        tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash)
3✔
148
        if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
5✔
149
                controlBlock.OutputKeyYIsOdd = true
2✔
150
        }
2✔
151

152
        return &waddrmgr.Tapscript{
3✔
153
                Type:         waddrmgr.TaprootKeySpendRootHash,
3✔
154
                ControlBlock: controlBlock,
3✔
155
                RootHash:     rootHash,
3✔
156
        }
3✔
157
}
158

159
// TapscriptFullKeyOnly creates a waddrmgr.Tapscript for the given full Taproot
160
// key.
161
func TapscriptFullKeyOnly(taprootKey *btcec.PublicKey) *waddrmgr.Tapscript {
3✔
162
        return &waddrmgr.Tapscript{
3✔
163
                Type:          waddrmgr.TaprootFullKeyOnly,
3✔
164
                FullOutputKey: taprootKey,
3✔
165
        }
3✔
166
}
3✔
167

168
// PayToTaprootScript creates a new script to pay to a version 1 (taproot)
169
// witness program. The passed public key will be serialized as an x-only key
170
// to create the witness program.
171
func PayToTaprootScript(taprootKey *btcec.PublicKey) ([]byte, error) {
3✔
172
        builder := txscript.NewScriptBuilder()
3✔
173

3✔
174
        builder.AddOp(txscript.OP_1)
3✔
175
        builder.AddData(schnorr.SerializePubKey(taprootKey))
3✔
176

3✔
177
        return builder.Script()
3✔
178
}
3✔
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