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

lightningnetwork / lnd / 13523316608

25 Feb 2025 02:12PM UTC coverage: 49.351% (-9.5%) from 58.835%
13523316608

Pull #9549

github

yyforyongyu
routing/chainview: refactor `TestFilteredChainView`

So each test has its own miner and chainView.
Pull Request #9549: Fix unit test flake `TestHistoricalConfDetailsTxIndex`

0 of 120 new or added lines in 1 file covered. (0.0%)

27196 existing lines in 434 files now uncovered.

100945 of 204543 relevant lines covered (49.35%)

1.54 hits per line

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

0.0
/input/test_utils.go
1
package input
2

3
import (
4
        "bytes"
5
        "encoding/hex"
6
        "fmt"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
10
        "github.com/btcsuite/btcd/btcec/v2/schnorr"
11
        "github.com/btcsuite/btcd/btcutil"
12
        "github.com/btcsuite/btcd/chaincfg"
13
        "github.com/btcsuite/btcd/chaincfg/chainhash"
14
        "github.com/btcsuite/btcd/txscript"
15
        "github.com/btcsuite/btcd/wire"
16
        "github.com/lightningnetwork/lnd/keychain"
17
)
18

19
var (
20

21
        // For simplicity a single priv key controls all of our test outputs.
22
        testWalletPrivKey = []byte{
23
                0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf,
24
                0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9,
25
                0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f,
26
                0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90,
27
        }
28

29
        // We're alice :)
30
        bobsPrivKey = []byte{
31
                0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
32
                0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
33
                0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
34
                0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
35
        }
36

37
        // Use a hard-coded HD seed.
38
        testHdSeed = chainhash.Hash{
39
                0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
40
                0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4,
41
                0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9,
42
                0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53,
43
        }
44
)
45

46
// MockSigner is a simple implementation of the Signer interface. Each one has
47
// a set of private keys in a slice and can sign messages using the appropriate
48
// one.
49
type MockSigner struct {
50
        Privkeys  []*btcec.PrivateKey
51
        NetParams *chaincfg.Params
52

53
        *MusigSessionManager
54
}
55

56
// NewMockSigner returns a new instance of the MockSigner given a set of
57
// backing private keys.
58
func NewMockSigner(privKeys []*btcec.PrivateKey,
UNCOV
59
        netParams *chaincfg.Params) *MockSigner {
×
UNCOV
60

×
UNCOV
61
        signer := &MockSigner{
×
UNCOV
62
                Privkeys:  privKeys,
×
UNCOV
63
                NetParams: netParams,
×
UNCOV
64
        }
×
UNCOV
65

×
UNCOV
66
        keyFetcher := func(*keychain.KeyDescriptor) (*btcec.PrivateKey, error) {
×
UNCOV
67
                return signer.Privkeys[0], nil
×
UNCOV
68
        }
×
UNCOV
69
        signer.MusigSessionManager = NewMusigSessionManager(keyFetcher)
×
UNCOV
70

×
UNCOV
71
        return signer
×
72
}
73

74
// SignOutputRaw generates a signature for the passed transaction according to
75
// the data within the passed SignDescriptor.
76
func (m *MockSigner) SignOutputRaw(tx *wire.MsgTx,
UNCOV
77
        signDesc *SignDescriptor) (Signature, error) {
×
UNCOV
78

×
UNCOV
79
        pubkey := signDesc.KeyDesc.PubKey
×
UNCOV
80
        switch {
×
UNCOV
81
        case signDesc.SingleTweak != nil:
×
UNCOV
82
                pubkey = TweakPubKeyWithTweak(pubkey, signDesc.SingleTweak)
×
UNCOV
83
        case signDesc.DoubleTweak != nil:
×
UNCOV
84
                pubkey = DeriveRevocationPubkey(pubkey, signDesc.DoubleTweak.PubKey())
×
85
        }
86

UNCOV
87
        hash160 := btcutil.Hash160(pubkey.SerializeCompressed())
×
UNCOV
88
        privKey := m.findKey(hash160, signDesc.SingleTweak, signDesc.DoubleTweak)
×
UNCOV
89
        if privKey == nil {
×
90
                return nil, fmt.Errorf("mock signer does not have key")
×
91
        }
×
92

93
        // In case of a taproot output any signature is always a Schnorr
94
        // signature, based on the new tapscript sighash algorithm.
UNCOV
95
        if txscript.IsPayToTaproot(signDesc.Output.PkScript) {
×
UNCOV
96
                sigHashes := txscript.NewTxSigHashes(
×
UNCOV
97
                        tx, signDesc.PrevOutputFetcher,
×
UNCOV
98
                )
×
UNCOV
99

×
UNCOV
100
                // Are we spending a script path or the key path? The API is
×
UNCOV
101
                // slightly different, so we need to account for that to get
×
UNCOV
102
                // the raw signature.
×
UNCOV
103
                var (
×
UNCOV
104
                        rawSig []byte
×
UNCOV
105
                        err    error
×
UNCOV
106
                )
×
UNCOV
107
                switch signDesc.SignMethod {
×
108
                case TaprootKeySpendBIP0086SignMethod,
UNCOV
109
                        TaprootKeySpendSignMethod:
×
UNCOV
110

×
UNCOV
111
                        // This function tweaks the private key using the tap
×
UNCOV
112
                        // root key supplied as the tweak.
×
UNCOV
113
                        rawSig, err = txscript.RawTxInTaprootSignature(
×
UNCOV
114
                                tx, sigHashes, signDesc.InputIndex,
×
UNCOV
115
                                signDesc.Output.Value, signDesc.Output.PkScript,
×
UNCOV
116
                                signDesc.TapTweak, signDesc.HashType,
×
UNCOV
117
                                privKey,
×
UNCOV
118
                        )
×
UNCOV
119
                        if err != nil {
×
120
                                return nil, err
×
121
                        }
×
122

UNCOV
123
                case TaprootScriptSpendSignMethod:
×
UNCOV
124
                        leaf := txscript.TapLeaf{
×
UNCOV
125
                                LeafVersion: txscript.BaseLeafVersion,
×
UNCOV
126
                                Script:      signDesc.WitnessScript,
×
UNCOV
127
                        }
×
UNCOV
128
                        rawSig, err = txscript.RawTxInTapscriptSignature(
×
UNCOV
129
                                tx, sigHashes, signDesc.InputIndex,
×
UNCOV
130
                                signDesc.Output.Value, signDesc.Output.PkScript,
×
UNCOV
131
                                leaf, signDesc.HashType, privKey,
×
UNCOV
132
                        )
×
UNCOV
133
                        if err != nil {
×
134
                                return nil, err
×
135
                        }
×
136
                }
137

138
                // The signature returned above might have a sighash flag
139
                // attached if a non-default type was used. We'll slice this
140
                // off if it exists to ensure we can properly parse the raw
141
                // signature.
UNCOV
142
                sig, err := schnorr.ParseSignature(
×
UNCOV
143
                        rawSig[:schnorr.SignatureSize],
×
UNCOV
144
                )
×
UNCOV
145
                if err != nil {
×
146
                        return nil, err
×
147
                }
×
148

UNCOV
149
                return sig, nil
×
150
        }
151

UNCOV
152
        sig, err := txscript.RawTxInWitnessSignature(
×
UNCOV
153
                tx, signDesc.SigHashes, signDesc.InputIndex,
×
UNCOV
154
                signDesc.Output.Value, signDesc.WitnessScript,
×
UNCOV
155
                signDesc.HashType, privKey,
×
UNCOV
156
        )
×
UNCOV
157
        if err != nil {
×
158
                return nil, err
×
159
        }
×
160

UNCOV
161
        return ecdsa.ParseDERSignature(sig[:len(sig)-1])
×
162
}
163

164
// ComputeInputScript generates a complete InputIndex for the passed transaction
165
// with the signature as defined within the passed SignDescriptor. This method
166
// should be capable of generating the proper input script for both regular
167
// p2wkh output and p2wkh outputs nested within a regular p2sh output.
168
func (m *MockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*Script, error) {
×
169
        scriptType, addresses, _, err := txscript.ExtractPkScriptAddrs(
×
170
                signDesc.Output.PkScript, m.NetParams)
×
171
        if err != nil {
×
172
                return nil, err
×
173
        }
×
174

175
        switch scriptType {
×
176
        case txscript.PubKeyHashTy:
×
177
                privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,
×
178
                        signDesc.DoubleTweak)
×
179
                if privKey == nil {
×
180
                        return nil, fmt.Errorf("mock signer does not have key for "+
×
181
                                "address %v", addresses[0])
×
182
                }
×
183

184
                sigScript, err := txscript.SignatureScript(
×
185
                        tx, signDesc.InputIndex, signDesc.Output.PkScript,
×
186
                        txscript.SigHashAll, privKey, true,
×
187
                )
×
188
                if err != nil {
×
189
                        return nil, err
×
190
                }
×
191

192
                return &Script{SigScript: sigScript}, nil
×
193

194
        case txscript.WitnessV0PubKeyHashTy:
×
195
                privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,
×
196
                        signDesc.DoubleTweak)
×
197
                if privKey == nil {
×
198
                        return nil, fmt.Errorf("mock signer does not have key for "+
×
199
                                "address %v", addresses[0])
×
200
                }
×
201

202
                witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
×
203
                        signDesc.InputIndex, signDesc.Output.Value,
×
204
                        signDesc.Output.PkScript, txscript.SigHashAll, privKey, true)
×
205
                if err != nil {
×
206
                        return nil, err
×
207
                }
×
208

209
                return &Script{Witness: witnessScript}, nil
×
210

211
        default:
×
212
                return nil, fmt.Errorf("unexpected script type: %v", scriptType)
×
213
        }
214
}
215

216
// findKey searches through all stored private keys and returns one
217
// corresponding to the hashed pubkey if it can be found. The public key may
218
// either correspond directly to the private key or to the private key with a
219
// tweak applied.
220
func (m *MockSigner) findKey(needleHash160 []byte, singleTweak []byte,
UNCOV
221
        doubleTweak *btcec.PrivateKey) *btcec.PrivateKey {
×
UNCOV
222

×
UNCOV
223
        for _, privkey := range m.Privkeys {
×
UNCOV
224
                // First check whether public key is directly derived from
×
UNCOV
225
                // private key.
×
UNCOV
226
                hash160 := btcutil.Hash160(privkey.PubKey().SerializeCompressed())
×
UNCOV
227
                if bytes.Equal(hash160, needleHash160) {
×
UNCOV
228
                        return privkey
×
UNCOV
229
                }
×
230

231
                // Otherwise check if public key is derived from tweaked
232
                // private key.
UNCOV
233
                switch {
×
UNCOV
234
                case singleTweak != nil:
×
UNCOV
235
                        privkey = TweakPrivKey(privkey, singleTweak)
×
UNCOV
236
                case doubleTweak != nil:
×
UNCOV
237
                        privkey = DeriveRevocationPrivKey(privkey, doubleTweak)
×
UNCOV
238
                default:
×
UNCOV
239
                        continue
×
240
                }
UNCOV
241
                hash160 = btcutil.Hash160(privkey.PubKey().SerializeCompressed())
×
UNCOV
242
                if bytes.Equal(hash160, needleHash160) {
×
UNCOV
243
                        return privkey
×
UNCOV
244
                }
×
245
        }
246
        return nil
×
247
}
248

249
// pubkeyFromHex parses a Bitcoin public key from a hex encoded string.
UNCOV
250
func pubkeyFromHex(keyHex string) (*btcec.PublicKey, error) {
×
UNCOV
251
        bytes, err := hex.DecodeString(keyHex)
×
UNCOV
252
        if err != nil {
×
253
                return nil, err
×
254
        }
×
UNCOV
255
        return btcec.ParsePubKey(bytes)
×
256
}
257

258
// privkeyFromHex parses a Bitcoin private key from a hex encoded string.
UNCOV
259
func privkeyFromHex(keyHex string) (*btcec.PrivateKey, error) {
×
UNCOV
260
        bytes, err := hex.DecodeString(keyHex)
×
UNCOV
261
        if err != nil {
×
262
                return nil, err
×
263
        }
×
UNCOV
264
        key, _ := btcec.PrivKeyFromBytes(bytes)
×
UNCOV
265
        return key, nil
×
266

267
}
268

269
// pubkeyToHex serializes a Bitcoin public key to a hex encoded string.
UNCOV
270
func pubkeyToHex(key *btcec.PublicKey) string {
×
UNCOV
271
        return hex.EncodeToString(key.SerializeCompressed())
×
UNCOV
272
}
×
273

274
// privkeyFromHex serializes a Bitcoin private key to a hex encoded string.
UNCOV
275
func privkeyToHex(key *btcec.PrivateKey) string {
×
UNCOV
276
        return hex.EncodeToString(key.Serialize())
×
UNCOV
277
}
×
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