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

lightningnetwork / lnd / 13586005509

28 Feb 2025 10:14AM UTC coverage: 68.629% (+9.9%) from 58.77%
13586005509

Pull #9521

github

web-flow
Merge 37d3a70a5 into 8532955b3
Pull Request #9521: unit: remove GOACC, use Go 1.20 native coverage functionality

129950 of 189351 relevant lines covered (68.63%)

23726.46 hits per line

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

85.89
/lnwire/writer.go
1
package lnwire
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "errors"
7
        "fmt"
8
        "image/color"
9
        "math"
10
        "net"
11

12
        "github.com/btcsuite/btcd/btcec/v2"
13
        "github.com/btcsuite/btcd/btcutil"
14
        "github.com/btcsuite/btcd/wire"
15
        "github.com/lightningnetwork/lnd/tor"
16
)
17

18
var (
19
        // ErrNilFeatureVector is returned when the supplied feature is nil.
20
        ErrNilFeatureVector = errors.New("cannot write nil feature vector")
21

22
        // ErrPkScriptTooLong is returned when the length of the provided
23
        // script exceeds 34.
24
        ErrPkScriptTooLong = errors.New("'PkScript' too long")
25

26
        // ErrNilTCPAddress is returned when the supplied address is nil.
27
        ErrNilTCPAddress = errors.New("cannot write nil TCPAddr")
28

29
        // ErrNilOnionAddress is returned when the supplied address is nil.
30
        ErrNilOnionAddress = errors.New("cannot write nil onion address")
31

32
        // ErrNilNetAddress is returned when a nil value is used in []net.Addr.
33
        ErrNilNetAddress = errors.New("cannot write nil address")
34

35
        // ErrNilOpaqueAddrs is returned when the supplied address is nil.
36
        ErrNilOpaqueAddrs = errors.New("cannot write nil OpaqueAddrs")
37

38
        // ErrNilPublicKey is returned when a nil pubkey is used.
39
        ErrNilPublicKey = errors.New("cannot write nil pubkey")
40

41
        // ErrUnknownServiceLength is returned when the onion service length is
42
        // unknown.
43
        ErrUnknownServiceLength = errors.New("unknown onion service length")
44
)
45

46
// ErrOutpointIndexTooBig is used when the outpoint index exceeds the max value
47
// of uint16.
48
func ErrOutpointIndexTooBig(index uint32) error {
3✔
49
        return fmt.Errorf(
3✔
50
                "index for outpoint (%v) is greater than "+
3✔
51
                        "max index of %v", index, math.MaxUint16,
3✔
52
        )
3✔
53
}
3✔
54

55
// WriteBytes appends the given bytes to the provided buffer.
56
func WriteBytes(buf *bytes.Buffer, b []byte) error {
88,746✔
57
        _, err := buf.Write(b)
88,746✔
58
        return err
88,746✔
59
}
88,746✔
60

61
// WriteUint8 appends the uint8 to the provided buffer.
62
func WriteUint8(buf *bytes.Buffer, n uint8) error {
4,003✔
63
        _, err := buf.Write([]byte{n})
4,003✔
64
        return err
4,003✔
65
}
4,003✔
66

67
// WriteUint16 appends the uint16 to the provided buffer. It encodes the
68
// integer using big endian byte order.
69
func WriteUint16(buf *bytes.Buffer, n uint16) error {
469,504✔
70
        var b [2]byte
469,504✔
71
        binary.BigEndian.PutUint16(b[:], n)
469,504✔
72
        _, err := buf.Write(b[:])
469,504✔
73
        return err
469,504✔
74
}
469,504✔
75

76
// WriteUint32 appends the uint32 to the provided buffer. It encodes the
77
// integer using big endian byte order.
78
func WriteUint32(buf *bytes.Buffer, n uint32) error {
181,762✔
79
        var b [4]byte
181,762✔
80
        binary.BigEndian.PutUint32(b[:], n)
181,762✔
81
        _, err := buf.Write(b[:])
181,762✔
82
        return err
181,762✔
83
}
181,762✔
84

85
// WriteUint64 appends the uint64 to the provided buffer. It encodes the
86
// integer using big endian byte order.
87
func WriteUint64(buf *bytes.Buffer, n uint64) error {
12,379✔
88
        var b [8]byte
12,379✔
89
        binary.BigEndian.PutUint64(b[:], n)
12,379✔
90
        _, err := buf.Write(b[:])
12,379✔
91
        return err
12,379✔
92
}
12,379✔
93

94
// WriteSatoshi appends the Satoshi value to the provided buffer.
95
func WriteSatoshi(buf *bytes.Buffer, amount btcutil.Amount) error {
939✔
96
        return WriteUint64(buf, uint64(amount))
939✔
97
}
939✔
98

99
// WriteMilliSatoshi appends the MilliSatoshi value to the provided buffer.
100
func WriteMilliSatoshi(buf *bytes.Buffer, amount MilliSatoshi) error {
5,452✔
101
        return WriteUint64(buf, uint64(amount))
5,452✔
102
}
5,452✔
103

104
// WritePublicKey appends the compressed public key to the provided buffer.
105
func WritePublicKey(buf *bytes.Buffer, pub *btcec.PublicKey) error {
1,990✔
106
        if pub == nil {
1,991✔
107
                return ErrNilPublicKey
1✔
108
        }
1✔
109

110
        serializedPubkey := pub.SerializeCompressed()
1,989✔
111
        return WriteBytes(buf, serializedPubkey)
1,989✔
112
}
113

114
// WriteChannelID appends the ChannelID to the provided buffer.
115
func WriteChannelID(buf *bytes.Buffer, channelID ChannelID) error {
11,943✔
116
        return WriteBytes(buf, channelID[:])
11,943✔
117
}
11,943✔
118

119
// WriteNodeAlias appends the alias to the provided buffer.
120
func WriteNodeAlias(buf *bytes.Buffer, alias NodeAlias) error {
306✔
121
        return WriteBytes(buf, alias[:])
306✔
122
}
306✔
123

124
// WriteShortChannelID appends the ShortChannelID to the provided buffer. It
125
// encodes the BlockHeight and TxIndex each using 3 bytes with big endian byte
126
// order, and encodes txPosition using 2 bytes with big endian byte order.
127
func WriteShortChannelID(buf *bytes.Buffer, shortChanID ShortChannelID) error {
457,088✔
128
        // Check that field fit in 3 bytes and write the blockHeight
457,088✔
129
        if shortChanID.BlockHeight > ((1 << 24) - 1) {
457,088✔
130
                return errors.New("block height should fit in 3 bytes")
×
131
        }
×
132

133
        var blockHeight [4]byte
457,088✔
134
        binary.BigEndian.PutUint32(blockHeight[:], shortChanID.BlockHeight)
457,088✔
135

457,088✔
136
        if _, err := buf.Write(blockHeight[1:]); err != nil {
457,088✔
137
                return err
×
138
        }
×
139

140
        // Check that field fit in 3 bytes and write the txIndex
141
        if shortChanID.TxIndex > ((1 << 24) - 1) {
457,088✔
142
                return errors.New("tx index should fit in 3 bytes")
×
143
        }
×
144

145
        var txIndex [4]byte
457,088✔
146
        binary.BigEndian.PutUint32(txIndex[:], shortChanID.TxIndex)
457,088✔
147
        if _, err := buf.Write(txIndex[1:]); err != nil {
457,088✔
148
                return err
×
149
        }
×
150

151
        // Write the TxPosition
152
        return WriteUint16(buf, shortChanID.TxPosition)
457,088✔
153
}
154

155
// WriteSig appends the signature to the provided buffer.
156
func WriteSig(buf *bytes.Buffer, sig Sig) error {
38,372✔
157
        return WriteBytes(buf, sig.bytes[:])
38,372✔
158
}
38,372✔
159

160
// WriteSigs appends the slice of signatures to the provided buffer with its
161
// length.
162
func WriteSigs(buf *bytes.Buffer, sigs []Sig) error {
4,260✔
163
        // Write the length of the sigs.
4,260✔
164
        if err := WriteUint16(buf, uint16(len(sigs))); err != nil {
4,260✔
165
                return err
×
166
        }
×
167

168
        for _, sig := range sigs {
36,533✔
169
                if err := WriteSig(buf, sig); err != nil {
32,273✔
170
                        return err
×
171
                }
×
172
        }
173
        return nil
4,260✔
174
}
175

176
// WriteFailCode appends the FailCode to the provided buffer.
177
func WriteFailCode(buf *bytes.Buffer, e FailCode) error {
122✔
178
        return WriteUint16(buf, uint16(e))
122✔
179
}
122✔
180

181
// WriteRawFeatureVector encodes the feature using the feature's Encode method
182
// and appends the data to the provided buffer. An error will return if the
183
// passed feature is nil.
184
func WriteRawFeatureVector(buf *bytes.Buffer, feature *RawFeatureVector) error {
2,029✔
185
        if feature == nil {
2,031✔
186
                return ErrNilFeatureVector
2✔
187
        }
2✔
188

189
        return feature.Encode(buf)
2,027✔
190
}
191

192
// WriteColorRGBA appends the RGBA color using three bytes.
193
func WriteColorRGBA(buf *bytes.Buffer, e color.RGBA) error {
306✔
194
        // Write R
306✔
195
        if err := WriteUint8(buf, e.R); err != nil {
306✔
196
                return err
×
197
        }
×
198

199
        // Write G
200
        if err := WriteUint8(buf, e.G); err != nil {
306✔
201
                return err
×
202
        }
×
203

204
        // Write B
205
        return WriteUint8(buf, e.B)
306✔
206
}
207

208
// WriteQueryEncoding appends the QueryEncoding to the provided buffer.
209
func WriteQueryEncoding(buf *bytes.Buffer, e QueryEncoding) error {
955✔
210
        return WriteUint8(buf, uint8(e))
955✔
211
}
955✔
212

213
// WriteFundingFlag appends the FundingFlag to the provided buffer.
214
func WriteFundingFlag(buf *bytes.Buffer, flag FundingFlag) error {
149✔
215
        return WriteUint8(buf, uint8(flag))
149✔
216
}
149✔
217

218
// WriteChanUpdateMsgFlags appends the update flag to the provided buffer.
219
func WriteChanUpdateMsgFlags(buf *bytes.Buffer, f ChanUpdateMsgFlags) error {
723✔
220
        return WriteUint8(buf, uint8(f))
723✔
221
}
723✔
222

223
// WriteChanUpdateChanFlags appends the update flag to the provided buffer.
224
func WriteChanUpdateChanFlags(buf *bytes.Buffer, f ChanUpdateChanFlags) error {
723✔
225
        return WriteUint8(buf, uint8(f))
723✔
226
}
723✔
227

228
// WriteDeliveryAddress appends the address to the provided buffer.
229
func WriteDeliveryAddress(buf *bytes.Buffer, addr DeliveryAddress) error {
119✔
230
        return writeDataWithLength(buf, addr)
119✔
231
}
119✔
232

233
// WritePingPayload appends the payload to the provided buffer.
234
func WritePingPayload(buf *bytes.Buffer, payload PingPayload) error {
106✔
235
        return writeDataWithLength(buf, payload)
106✔
236
}
106✔
237

238
// WritePongPayload appends the payload to the provided buffer.
239
func WritePongPayload(buf *bytes.Buffer, payload PongPayload) error {
104✔
240
        return writeDataWithLength(buf, payload)
104✔
241
}
104✔
242

243
// WriteWarningData appends the data to the provided buffer.
244
func WriteWarningData(buf *bytes.Buffer, data WarningData) error {
104✔
245
        return writeDataWithLength(buf, data)
104✔
246
}
104✔
247

248
// WriteErrorData appends the data to the provided buffer.
249
func WriteErrorData(buf *bytes.Buffer, data ErrorData) error {
109✔
250
        return writeDataWithLength(buf, data)
109✔
251
}
109✔
252

253
// WriteOpaqueReason appends the reason to the provided buffer.
254
func WriteOpaqueReason(buf *bytes.Buffer, reason OpaqueReason) error {
796✔
255
        return writeDataWithLength(buf, reason)
796✔
256
}
796✔
257

258
// WriteBool appends the boolean to the provided buffer.
259
func WriteBool(buf *bytes.Buffer, b bool) error {
261✔
260
        if b {
306✔
261
                return WriteBytes(buf, []byte{1})
45✔
262
        }
45✔
263
        return WriteBytes(buf, []byte{0})
219✔
264
}
265

266
// WritePkScript appends the script to the provided buffer. Returns an error if
267
// the provided script exceeds 34 bytes.
268
func WritePkScript(buf *bytes.Buffer, s PkScript) error {
2✔
269
        // The largest script we'll accept is a p2wsh which is exactly
2✔
270
        // 34 bytes long.
2✔
271
        scriptLength := len(s)
2✔
272
        if scriptLength > 34 {
3✔
273
                return ErrPkScriptTooLong
1✔
274
        }
1✔
275

276
        return wire.WriteVarBytes(buf, 0, s)
1✔
277
}
278

279
// WriteOutPoint appends the outpoint to the provided buffer.
280
func WriteOutPoint(buf *bytes.Buffer, p wire.OutPoint) error {
126✔
281
        // Before we write anything to the buffer, check the Index is sane.
126✔
282
        if p.Index > math.MaxUint16 {
128✔
283
                return ErrOutpointIndexTooBig(p.Index)
2✔
284
        }
2✔
285

286
        var h [32]byte
124✔
287
        copy(h[:], p.Hash[:])
124✔
288
        if _, err := buf.Write(h[:]); err != nil {
124✔
289
                return err
×
290
        }
×
291

292
        // Write the index using two bytes.
293
        return WriteUint16(buf, uint16(p.Index))
124✔
294
}
295

296
// WriteTCPAddr appends the TCP address to the provided buffer, either a IPv4
297
// or a IPv6.
298
func WriteTCPAddr(buf *bytes.Buffer, addr *net.TCPAddr) error {
3,462✔
299
        if addr == nil {
3,463✔
300
                return ErrNilTCPAddress
1✔
301
        }
1✔
302

303
        // Make a slice of bytes to hold the data of descriptor and ip. At
304
        // most, we need 17 bytes - 1 byte for the descriptor, 16 bytes for
305
        // IPv6.
306
        data := make([]byte, 0, 17)
3,461✔
307

3,461✔
308
        if addr.IP.To4() != nil {
5,121✔
309
                data = append(data, uint8(tcp4Addr))
1,660✔
310
                data = append(data, addr.IP.To4()...)
1,660✔
311
        } else {
3,464✔
312
                data = append(data, uint8(tcp6Addr))
1,804✔
313
                data = append(data, addr.IP.To16()...)
1,804✔
314
        }
1,804✔
315

316
        if _, err := buf.Write(data); err != nil {
3,461✔
317
                return err
×
318
        }
×
319

320
        return WriteUint16(buf, uint16(addr.Port))
3,461✔
321
}
322

323
// WriteOnionAddr appends the onion address to the provided buffer.
324
func WriteOnionAddr(buf *bytes.Buffer, addr *tor.OnionAddr) error {
1,247✔
325
        if addr == nil {
1,248✔
326
                return ErrNilOnionAddress
1✔
327
        }
1✔
328

329
        var (
1,246✔
330
                suffixIndex int
1,246✔
331
                descriptor  []byte
1,246✔
332
        )
1,246✔
333

1,246✔
334
        // Decide the suffixIndex and descriptor.
1,246✔
335
        switch len(addr.OnionService) {
1,246✔
336
        case tor.V2Len:
856✔
337
                descriptor = []byte{byte(v2OnionAddr)}
856✔
338
                suffixIndex = tor.V2Len - tor.OnionSuffixLen
856✔
339

340
        case tor.V3Len:
392✔
341
                descriptor = []byte{byte(v3OnionAddr)}
392✔
342
                suffixIndex = tor.V3Len - tor.OnionSuffixLen
392✔
343

344
        default:
1✔
345
                return ErrUnknownServiceLength
1✔
346
        }
347

348
        // Decode the address.
349
        host, err := tor.Base32Encoding.DecodeString(
1,245✔
350
                addr.OnionService[:suffixIndex],
1,245✔
351
        )
1,245✔
352
        if err != nil {
1,246✔
353
                return err
1✔
354
        }
1✔
355

356
        // Perform the actual write when the above checks passed.
357
        if _, err := buf.Write(descriptor); err != nil {
1,244✔
358
                return err
×
359
        }
×
360
        if _, err := buf.Write(host); err != nil {
1,244✔
361
                return err
×
362
        }
×
363

364
        return WriteUint16(buf, uint16(addr.Port))
1,244✔
365
}
366

367
// WriteOpaqueAddrs appends the payload of the given OpaqueAddrs to buffer.
368
func WriteOpaqueAddrs(buf *bytes.Buffer, addr *OpaqueAddrs) error {
236✔
369
        if addr == nil {
236✔
370
                return ErrNilOpaqueAddrs
×
371
        }
×
372

373
        _, err := buf.Write(addr.Payload)
236✔
374
        return err
236✔
375
}
376

377
// WriteNetAddrs appends a slice of addresses to the provided buffer with the
378
// length info.
379
func WriteNetAddrs(buf *bytes.Buffer, addresses []net.Addr) error {
309✔
380
        // First, we'll encode all the addresses into an intermediate
309✔
381
        // buffer. We need to do this in order to compute the total
309✔
382
        // length of the addresses.
309✔
383
        buffer := make([]byte, 0, MaxMsgBody)
309✔
384
        addrBuf := bytes.NewBuffer(buffer)
309✔
385

309✔
386
        for _, address := range addresses {
5,244✔
387
                switch a := address.(type) {
4,935✔
388
                case *net.TCPAddr:
3,459✔
389
                        if err := WriteTCPAddr(addrBuf, a); err != nil {
3,459✔
390
                                return err
×
391
                        }
×
392
                case *tor.OnionAddr:
1,242✔
393
                        if err := WriteOnionAddr(addrBuf, a); err != nil {
1,242✔
394
                                return err
×
395
                        }
×
396
                case *OpaqueAddrs:
236✔
397
                        if err := WriteOpaqueAddrs(addrBuf, a); err != nil {
236✔
398
                                return err
×
399
                        }
×
400
                default:
1✔
401
                        return ErrNilNetAddress
1✔
402
                }
403
        }
404

405
        // With the addresses fully encoded, we can now write out data.
406
        return writeDataWithLength(buf, addrBuf.Bytes())
308✔
407
}
408

409
// writeDataWithLength writes the data and its length to the buffer.
410
func writeDataWithLength(buf *bytes.Buffer, data []byte) error {
1,637✔
411
        var l [2]byte
1,637✔
412
        binary.BigEndian.PutUint16(l[:], uint16(len(data)))
1,637✔
413
        if _, err := buf.Write(l[:]); err != nil {
1,637✔
414
                return err
×
415
        }
×
416

417
        _, err := buf.Write(data)
1,637✔
418
        return err
1,637✔
419
}
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