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

lightningnetwork / lnd / 15280233992

27 May 2025 04:07PM UTC coverage: 58.56% (+0.6%) from 57.977%
15280233992

Pull #9455

github

web-flow
Merge 015c776a9 into 93a6ab875
Pull Request #9455: discovery+lnwire: add support for DNS host name in NodeAnnouncement msg

145 of 291 new or added lines in 7 files covered. (49.83%)

120 existing lines in 10 files now uncovered.

97608 of 166681 relevant lines covered (58.56%)

1.82 hits per line

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

0.0
/lnwire/test_utils.go
1
package lnwire
2

3
import (
4
        "crypto/sha256"
5
        "fmt"
6
        "net"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
10
        "github.com/btcsuite/btcd/chaincfg/chainhash"
11
        "github.com/btcsuite/btcd/wire"
12
        "github.com/lightningnetwork/lnd/fn/v2"
13
        "github.com/lightningnetwork/lnd/tor"
14
        "github.com/stretchr/testify/require"
15
        "pgregory.net/rapid"
16
)
17

18
// RandChannelUpdate generates a random ChannelUpdate message using rapid's
19
// generators.
20
func RandPartialSig(t *rapid.T) *PartialSig {
×
21
        // Generate random private key bytes
×
22
        sigBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "privKeyBytes")
×
23

×
24
        var s btcec.ModNScalar
×
25
        s.SetByteSlice(sigBytes)
×
26

×
27
        return &PartialSig{
×
28
                Sig: s,
×
29
        }
×
30
}
×
31

32
// RandPartialSigWithNonce generates a random PartialSigWithNonce using rapid
33
// generators.
34
func RandPartialSigWithNonce(t *rapid.T) *PartialSigWithNonce {
×
35
        sigLen := rapid.IntRange(1, 65).Draw(t, "partialSigLen")
×
36
        sigBytes := rapid.SliceOfN(
×
37
                rapid.Byte(), sigLen, sigLen,
×
38
        ).Draw(t, "partialSig")
×
39

×
40
        sigScalar := new(btcec.ModNScalar)
×
41
        sigScalar.SetByteSlice(sigBytes)
×
42

×
43
        return NewPartialSigWithNonce(
×
44
                RandMusig2Nonce(t), *sigScalar,
×
45
        )
×
46
}
×
47

48
// RandPubKey generates a random public key using rapid's generators.
49
func RandPubKey(t *rapid.T) *btcec.PublicKey {
×
50
        privKeyBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(
×
51
                t, "privKeyBytes",
×
52
        )
×
53
        _, pub := btcec.PrivKeyFromBytes(privKeyBytes)
×
54

×
55
        return pub
×
56
}
×
57

58
// RandChannelID generates a random channel ID.
59
func RandChannelID(t *rapid.T) ChannelID {
×
60
        var c ChannelID
×
61
        bytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "channelID")
×
62
        copy(c[:], bytes)
×
63

×
64
        return c
×
65
}
×
66

67
// RandShortChannelID generates a random short channel ID.
68
func RandShortChannelID(t *rapid.T) ShortChannelID {
×
69
        return NewShortChanIDFromInt(
×
70
                uint64(rapid.IntRange(1, 100000).Draw(t, "shortChanID")),
×
71
        )
×
72
}
×
73

74
// RandFeatureVector generates a random feature vector.
75
func RandFeatureVector(t *rapid.T) *RawFeatureVector {
×
76
        featureVec := NewRawFeatureVector()
×
77

×
78
        // Add a random number of random feature bits
×
79
        numFeatures := rapid.IntRange(0, 20).Draw(t, "numFeatures")
×
80
        for i := 0; i < numFeatures; i++ {
×
81
                bit := FeatureBit(rapid.IntRange(0, 100).Draw(
×
82
                        t, fmt.Sprintf("featureBit-%d", i)),
×
83
                )
×
84
                featureVec.Set(bit)
×
85
        }
×
86

87
        return featureVec
×
88
}
89

90
// RandSignature generates a signature for testing.
91
func RandSignature(t *rapid.T) Sig {
×
92
        testRScalar := new(btcec.ModNScalar)
×
93
        testSScalar := new(btcec.ModNScalar)
×
94

×
95
        // Generate random bytes for R and S
×
96
        rBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "rBytes")
×
97
        sBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "sBytes")
×
98
        _ = testRScalar.SetByteSlice(rBytes)
×
99
        _ = testSScalar.SetByteSlice(sBytes)
×
100

×
101
        testSig := ecdsa.NewSignature(testRScalar, testSScalar)
×
102

×
103
        sig, err := NewSigFromSignature(testSig)
×
104
        if err != nil {
×
105
                panic(fmt.Sprintf("unable to create signature: %v", err))
×
106
        }
107

108
        return sig
×
109
}
110

111
// RandPaymentHash generates a random payment hash.
112
func RandPaymentHash(t *rapid.T) [32]byte {
×
113
        var hash [32]byte
×
114
        bytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "paymentHash")
×
115
        copy(hash[:], bytes)
×
116

×
117
        return hash
×
118
}
×
119

120
// RandPaymentPreimage generates a random payment preimage.
121
func RandPaymentPreimage(t *rapid.T) [32]byte {
×
122
        var preimage [32]byte
×
123
        bytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "preimage")
×
124
        copy(preimage[:], bytes)
×
125

×
126
        return preimage
×
127
}
×
128

129
// RandChainHash generates a random chain hash.
130
func RandChainHash(t *rapid.T) chainhash.Hash {
×
131
        var hash [32]byte
×
132
        bytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "chainHash")
×
133
        copy(hash[:], bytes)
×
134

×
135
        return hash
×
136
}
×
137

138
// RandNodeAlias generates a random node alias.
139
func RandNodeAlias(t *rapid.T) NodeAlias {
×
140
        var alias NodeAlias
×
141
        aliasLength := rapid.IntRange(0, 32).Draw(t, "aliasLength")
×
142

×
143
        aliasBytes := rapid.StringN(
×
144
                0, aliasLength, aliasLength,
×
145
        ).Draw(t, "alias")
×
146

×
147
        copy(alias[:], aliasBytes)
×
148

×
149
        return alias
×
150
}
×
151

152
// RandNetAddrs generates random network addresses.
153
func RandNetAddrs(t *rapid.T) []net.Addr {
×
NEW
154
        numAddresses := rapid.IntRange(0, 7).Draw(t, "numAddresses")
×
155
        if numAddresses == 0 {
×
156
                return nil
×
157
        }
×
158

159
        addresses := make([]net.Addr, numAddresses)
×
NEW
160
        var dnsAddrIncluded bool
×
161
        for i := 0; i < numAddresses; i++ {
×
NEW
162
                var maxType int
×
NEW
163
                if dnsAddrIncluded {
×
NEW
164
                        // Only allow address types 0-3 (exclude DNSAddr).
×
NEW
165
                        maxType = 3
×
NEW
166
                } else {
×
NEW
167
                        // Allow all types including DNSAddr.
×
NEW
168
                        maxType = 4
×
NEW
169
                }
×
NEW
170
                addressType := rapid.IntRange(0, maxType).Draw(
×
171
                        t, fmt.Sprintf("addressType-%d", i),
×
172
                )
×
173

×
174
                switch addressType {
×
175
                // IPv4.
176
                case 0:
×
177
                        ipBytes := rapid.SliceOfN(rapid.Byte(), 4, 4).Draw(
×
178
                                t, fmt.Sprintf("ipv4-%d", i),
×
179
                        )
×
180
                        port := rapid.IntRange(1, 65535).Draw(
×
181
                                t, fmt.Sprintf("port-%d", i),
×
182
                        )
×
183
                        addresses[i] = &net.TCPAddr{
×
184
                                IP:   ipBytes,
×
185
                                Port: port,
×
186
                        }
×
187

188
                // IPv6.
189
                case 1:
×
190
                        ipBytes := rapid.SliceOfN(rapid.Byte(), 16, 16).Draw(
×
191
                                t, fmt.Sprintf("ipv6-%d", i),
×
192
                        )
×
193
                        port := rapid.IntRange(1, 65535).Draw(
×
194
                                t, fmt.Sprintf("port-%d", i),
×
195
                        )
×
196
                        addresses[i] = &net.TCPAddr{
×
197
                                IP:   ipBytes,
×
198
                                Port: port,
×
199
                        }
×
200

201
                // OnionAddr v2.
NEW
202
                case 2:
×
NEW
203
                        // V2 onion address (16 chars + .onion).
×
NEW
204
                        v2Bytes := rapid.SliceOfN(rapid.Byte(), 10, 10).Draw(
×
NEW
205
                                t, fmt.Sprintf("onion-service-v2-%d", i),
×
NEW
206
                        )
×
NEW
207
                        encoded := tor.Base32Encoding.EncodeToString(v2Bytes)
×
NEW
208
                        onionService := encoded[:16] + ".onion"
×
NEW
209

×
NEW
210
                        port := rapid.IntRange(1, 65535).Draw(
×
NEW
211
                                t, fmt.Sprintf("port-%d", i),
×
NEW
212
                        )
×
NEW
213
                        addresses[i] = &tor.OnionAddr{
×
NEW
214
                                OnionService: onionService,
×
NEW
215
                                Port:         port,
×
NEW
216
                        }
×
217

218
                // OnionAddr v3.
NEW
219
                case 3:
×
NEW
220
                        // V3 onion address (56 chars + .onion).
×
NEW
221
                        v3Bytes := rapid.SliceOfN(rapid.Byte(), 35, 35).Draw(
×
NEW
222
                                t, fmt.Sprintf("v3Bytes-%d", i),
×
NEW
223
                        )
×
NEW
224
                        encoded := tor.Base32Encoding.EncodeToString(v3Bytes)
×
NEW
225
                        onionService := encoded[:56] + ".onion"
×
NEW
226

×
NEW
227
                        port := rapid.IntRange(1, 65535).Draw(
×
NEW
228
                                t, fmt.Sprintf("port-%d", i),
×
NEW
229
                        )
×
NEW
230
                        addresses[i] = &tor.OnionAddr{
×
NEW
231
                                OnionService: onionService,
×
NEW
232
                                Port:         port,
×
NEW
233
                        }
×
234

235
                // DNSAddr.
NEW
236
                case 4:
×
NEW
237
                        // Ensure DNS address is included once in the
×
NEW
238
                        // random net addresses to ensure compliance with
×
NEW
239
                        // Bolt-07 requirements.
×
NEW
240
                        dnsAddrIncluded = true
×
NEW
241

×
NEW
242
                        // Simple domain name like example.com.
×
NEW
243
                        hostname := rapid.StringMatching(
×
NEW
244
                                `[a-z][a-z0-9]{3,28}\.(com|net|org)`,
×
NEW
245
                        ).Draw(t, fmt.Sprintf("hostname-%d", i))
×
NEW
246

×
NEW
247
                        port := rapid.IntRange(1, 65535).Draw(
×
NEW
248
                                t, fmt.Sprintf("port-%d", i),
×
NEW
249
                        )
×
NEW
250
                        addresses[i] = &DNSAddr{
×
NEW
251
                                Hostname: hostname,
×
NEW
252
                                Port:     port,
×
NEW
253
                        }
×
254
                }
255
        }
256

257
        return addresses
×
258
}
259

260
// RandCustomRecords generates random custom TLV records.
261
func RandCustomRecords(t *rapid.T,
262
        ignoreRecords fn.Set[uint64],
263
        custom bool) (CustomRecords, fn.Set[uint64]) {
×
264

×
265
        numRecords := rapid.IntRange(0, 5).Draw(t, "numCustomRecords")
×
266
        customRecords := make(CustomRecords)
×
267

×
268
        if numRecords == 0 {
×
269
                return nil, nil
×
270
        }
×
271

272
        rangeStart := 0
×
273
        rangeStop := int(CustomTypeStart)
×
274
        if custom {
×
275
                rangeStart = 70_000
×
276
                rangeStop = 100_000
×
277
        }
×
278

279
        ignoreSet := fn.NewSet[uint64]()
×
280
        for i := 0; i < numRecords; i++ {
×
281
                recordType := uint64(
×
282
                        rapid.IntRange(rangeStart, rangeStop).
×
283
                                Filter(func(i int) bool {
×
284
                                        return !ignoreRecords.Contains(
×
285
                                                uint64(i),
×
286
                                        )
×
287
                                }).
×
288
                                Draw(
289
                                        t, fmt.Sprintf("recordType-%d", i),
290
                                ),
291
                )
292
                recordLen := rapid.IntRange(4, 64).Draw(
×
293
                        t, fmt.Sprintf("recordLen-%d", i),
×
294
                )
×
295
                record := rapid.SliceOfN(
×
296
                        rapid.Byte(), recordLen, recordLen,
×
297
                ).Draw(t, fmt.Sprintf("record-%d", i))
×
298

×
299
                customRecords[recordType] = record
×
300

×
301
                ignoreSet.Add(recordType)
×
302
        }
303

304
        return customRecords, ignoreSet
×
305
}
306

307
// RandMusig2Nonce generates a random musig2 nonce.
308
func RandMusig2Nonce(t *rapid.T) Musig2Nonce {
×
309
        var nonce Musig2Nonce
×
310
        bytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "nonce")
×
311
        copy(nonce[:], bytes)
×
312

×
313
        return nonce
×
314
}
×
315

316
// RandExtraOpaqueData generates random extra opaque data.
317
func RandExtraOpaqueData(t *rapid.T,
318
        ignoreRecords fn.Set[uint64]) ExtraOpaqueData {
×
319

×
320
        // Make some random records.
×
321
        cRecords, _ := RandCustomRecords(t, ignoreRecords, false)
×
322
        if cRecords == nil {
×
323
                return ExtraOpaqueData{}
×
324
        }
×
325

326
        // Encode those records as opaque data.
327
        recordBytes, err := cRecords.Serialize()
×
328
        require.NoError(t, err)
×
329

×
330
        return ExtraOpaqueData(recordBytes)
×
331
}
332

333
// RandOpaqueReason generates a random opaque reason for HTLC failures.
334
func RandOpaqueReason(t *rapid.T) OpaqueReason {
×
335
        reasonLen := rapid.IntRange(32, 300).Draw(t, "reasonLen")
×
336
        return rapid.SliceOfN(rapid.Byte(), reasonLen, reasonLen).Draw(
×
337
                t, "opaqueReason",
×
338
        )
×
339
}
×
340

341
// RandFailCode generates a random HTLC failure code.
342
func RandFailCode(t *rapid.T) FailCode {
×
343
        // List of known failure codes to choose from Using only the documented
×
344
        // codes.
×
345
        validCodes := []FailCode{
×
346
                CodeInvalidRealm,
×
347
                CodeTemporaryNodeFailure,
×
348
                CodePermanentNodeFailure,
×
349
                CodeRequiredNodeFeatureMissing,
×
350
                CodePermanentChannelFailure,
×
351
                CodeRequiredChannelFeatureMissing,
×
352
                CodeUnknownNextPeer,
×
353
                CodeIncorrectOrUnknownPaymentDetails,
×
354
                CodeIncorrectPaymentAmount,
×
355
                CodeFinalExpiryTooSoon,
×
356
                CodeInvalidOnionVersion,
×
357
                CodeInvalidOnionHmac,
×
358
                CodeInvalidOnionKey,
×
359
                CodeTemporaryChannelFailure,
×
360
                CodeChannelDisabled,
×
361
                CodeExpiryTooSoon,
×
362
                CodeMPPTimeout,
×
363
                CodeInvalidOnionPayload,
×
364
                CodeFeeInsufficient,
×
365
        }
×
366

×
367
        // Choose a random code from the list.
×
368
        idx := rapid.IntRange(0, len(validCodes)-1).Draw(t, "failCodeIndex")
×
369

×
370
        return validCodes[idx]
×
371
}
×
372

373
// RandSHA256Hash generates a random SHA256 hash.
374
func RandSHA256Hash(t *rapid.T) [sha256.Size]byte {
×
375
        var hash [sha256.Size]byte
×
376
        bytes := rapid.SliceOfN(rapid.Byte(), sha256.Size, sha256.Size).Draw(
×
377
                t, "sha256Hash",
×
378
        )
×
379
        copy(hash[:], bytes)
×
380

×
381
        return hash
×
382
}
×
383

384
// RandDeliveryAddress generates a random delivery address (script).
385
func RandDeliveryAddress(t *rapid.T) DeliveryAddress {
×
386
        addrLen := rapid.IntRange(1, 34).Draw(t, "addrLen")
×
387

×
388
        return rapid.SliceOfN(rapid.Byte(), addrLen, addrLen).Draw(
×
389
                t, "deliveryAddress",
×
390
        )
×
391
}
×
392

393
// RandChannelType generates a random channel type.
394
func RandChannelType(t *rapid.T) *ChannelType {
×
395
        vec := RandFeatureVector(t)
×
396
        chanType := ChannelType(*vec)
×
397

×
398
        return &chanType
×
399
}
×
400

401
// RandLeaseExpiry generates a random lease expiry.
402
func RandLeaseExpiry(t *rapid.T) *LeaseExpiry {
×
403
        exp := LeaseExpiry(
×
404
                uint32(rapid.IntRange(1000, 1000000).Draw(t, "leaseExpiry")),
×
405
        )
×
406

×
407
        return &exp
×
408
}
×
409

410
// RandOutPoint generates a random transaction outpoint.
411
func RandOutPoint(t *rapid.T) wire.OutPoint {
×
412
        // Generate a random transaction ID
×
413
        var txid chainhash.Hash
×
414
        txidBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "txid")
×
415
        copy(txid[:], txidBytes)
×
416

×
417
        // Generate a random output index
×
418
        vout := uint32(rapid.IntRange(0, 10).Draw(t, "vout"))
×
419

×
420
        return wire.OutPoint{
×
421
                Hash:  txid,
×
422
                Index: vout,
×
423
        }
×
424
}
×
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