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

lightningnetwork / lnd / 19924300449

04 Dec 2025 09:35AM UTC coverage: 53.479% (-1.9%) from 55.404%
19924300449

Pull #10419

github

web-flow
Merge f811805c6 into 20473482d
Pull Request #10419: [docs] Document use-native-sql=true for SQL migration step 2

110496 of 206616 relevant lines covered (53.48%)

21221.61 hits per line

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

94.57
/lnwire/message.go
1
// Copyright (c) 2013-2017 The btcsuite developers
2
// Copyright (c) 2015-2016 The Decred developers
3
// code derived from https://github .com/btcsuite/btcd/blob/master/wire/message.go
4
// Copyright (C) 2015-2022 The Lightning Network Developers
5

6
package lnwire
7

8
import (
9
        "bytes"
10
        "encoding/binary"
11
        "fmt"
12
        "io"
13
)
14

15
// MessageTypeSize is the size in bytes of the message type field in the header
16
// of all messages.
17
const MessageTypeSize = 2
18

19
// MessageType is the unique 2 byte big-endian integer that indicates the type
20
// of message on the wire. All messages have a very simple header which
21
// consists simply of 2-byte message type. We omit a length field, and checksum
22
// as the Lightning Protocol is intended to be encapsulated within a
23
// confidential+authenticated cryptographic messaging protocol.
24
type MessageType uint16
25

26
// The currently defined message types within this current version of the
27
// Lightning protocol.
28
const (
29
        MsgWarning                 MessageType = 1
30
        MsgStfu                                = 2
31
        MsgInit                                = 16
32
        MsgError                               = 17
33
        MsgPing                                = 18
34
        MsgPong                                = 19
35
        MsgOpenChannel                         = 32
36
        MsgAcceptChannel                       = 33
37
        MsgFundingCreated                      = 34
38
        MsgFundingSigned                       = 35
39
        MsgChannelReady                        = 36
40
        MsgShutdown                            = 38
41
        MsgClosingSigned                       = 39
42
        MsgClosingComplete                     = 40
43
        MsgClosingSig                          = 41
44
        MsgDynPropose                          = 111
45
        MsgDynAck                              = 113
46
        MsgDynReject                           = 115
47
        MsgDynCommit                           = 117
48
        MsgUpdateAddHTLC                       = 128
49
        MsgUpdateFulfillHTLC                   = 130
50
        MsgUpdateFailHTLC                      = 131
51
        MsgCommitSig                           = 132
52
        MsgRevokeAndAck                        = 133
53
        MsgUpdateFee                           = 134
54
        MsgUpdateFailMalformedHTLC             = 135
55
        MsgChannelReestablish                  = 136
56
        MsgChannelAnnouncement                 = 256
57
        MsgNodeAnnouncement                    = 257
58
        MsgChannelUpdate                       = 258
59
        MsgAnnounceSignatures                  = 259
60
        MsgAnnounceSignatures2                 = 260
61
        MsgQueryShortChanIDs                   = 261
62
        MsgReplyShortChanIDsEnd                = 262
63
        MsgQueryChannelRange                   = 263
64
        MsgReplyChannelRange                   = 264
65
        MsgGossipTimestampRange                = 265
66
        MsgChannelAnnouncement2                = 267
67
        MsgNodeAnnouncement2                   = 269
68
        MsgChannelUpdate2                      = 271
69
        MsgOnionMessage                        = 513
70
        MsgKickoffSig                          = 777
71

72
        // MsgEnd defines the end of the official message range of the protocol.
73
        // If a new message is added beyond this message, then this should be
74
        // modified.
75
        MsgEnd = 778
76
)
77

78
// IsChannelUpdate is a filter function that discerns channel update messages
79
// from the other messages in the Lightning Network Protocol.
80
func (t MessageType) IsChannelUpdate() bool {
3,720✔
81
        switch t {
3,720✔
82
        case MsgUpdateAddHTLC:
930✔
83
                return true
930✔
84
        case MsgUpdateFulfillHTLC:
250✔
85
                return true
250✔
86
        case MsgUpdateFailHTLC:
138✔
87
                return true
138✔
88
        case MsgUpdateFailMalformedHTLC:
3✔
89
                return true
3✔
90
        case MsgUpdateFee:
3✔
91
                return true
3✔
92
        default:
2,396✔
93
                return false
2,396✔
94
        }
95
}
96

97
// ErrorEncodeMessage is used when failed to encode the message payload.
98
func ErrorEncodeMessage(err error) error {
4✔
99
        return fmt.Errorf("failed to encode message to buffer, got %w", err)
4✔
100
}
4✔
101

102
// ErrorWriteMessageType is used when failed to write the message type.
103
func ErrorWriteMessageType(err error) error {
×
104
        return fmt.Errorf("failed to write message type, got %w", err)
×
105
}
×
106

107
// ErrorPayloadTooLarge is used when the payload size exceeds the
108
// MaxMsgBody.
109
func ErrorPayloadTooLarge(size int) error {
2✔
110
        return fmt.Errorf(
2✔
111
                "message payload is too large - encoded %d bytes, "+
2✔
112
                        "but maximum message payload is %d bytes",
2✔
113
                size, MaxMsgBody,
2✔
114
        )
2✔
115
}
2✔
116

117
// String return the string representation of message type.
118
func (t MessageType) String() string {
42✔
119
        switch t {
42✔
120
        case MsgWarning:
1✔
121
                return "Warning"
1✔
122
        case MsgStfu:
1✔
123
                return "Stfu"
1✔
124
        case MsgInit:
1✔
125
                return "Init"
1✔
126
        case MsgOpenChannel:
1✔
127
                return "MsgOpenChannel"
1✔
128
        case MsgAcceptChannel:
1✔
129
                return "MsgAcceptChannel"
1✔
130
        case MsgFundingCreated:
1✔
131
                return "MsgFundingCreated"
1✔
132
        case MsgFundingSigned:
1✔
133
                return "MsgFundingSigned"
1✔
134
        case MsgChannelReady:
1✔
135
                return "ChannelReady"
1✔
136
        case MsgShutdown:
1✔
137
                return "Shutdown"
1✔
138
        case MsgClosingSigned:
1✔
139
                return "ClosingSigned"
1✔
140
        case MsgDynPropose:
1✔
141
                return "DynPropose"
1✔
142
        case MsgDynAck:
1✔
143
                return "DynAck"
1✔
144
        case MsgDynReject:
1✔
145
                return "DynReject"
1✔
146
        case MsgDynCommit:
1✔
147
                return "DynCommit"
1✔
148
        case MsgKickoffSig:
1✔
149
                return "KickoffSig"
1✔
150
        case MsgUpdateAddHTLC:
1✔
151
                return "UpdateAddHTLC"
1✔
152
        case MsgUpdateFailHTLC:
1✔
153
                return "UpdateFailHTLC"
1✔
154
        case MsgUpdateFulfillHTLC:
1✔
155
                return "UpdateFulfillHTLC"
1✔
156
        case MsgCommitSig:
1✔
157
                return "CommitSig"
1✔
158
        case MsgRevokeAndAck:
1✔
159
                return "RevokeAndAck"
1✔
160
        case MsgUpdateFailMalformedHTLC:
1✔
161
                return "UpdateFailMalformedHTLC"
1✔
162
        case MsgChannelReestablish:
1✔
163
                return "ChannelReestablish"
1✔
164
        case MsgError:
1✔
165
                return "Error"
1✔
166
        case MsgChannelAnnouncement:
1✔
167
                return "ChannelAnnouncement"
1✔
168
        case MsgChannelUpdate:
1✔
169
                return "ChannelUpdate"
1✔
170
        case MsgNodeAnnouncement:
1✔
171
                return "NodeAnnouncement1"
1✔
172
        case MsgPing:
1✔
173
                return "Ping"
1✔
174
        case MsgAnnounceSignatures:
1✔
175
                return "AnnounceSignatures"
1✔
176
        case MsgPong:
1✔
177
                return "Pong"
1✔
178
        case MsgUpdateFee:
1✔
179
                return "UpdateFee"
1✔
180
        case MsgQueryShortChanIDs:
1✔
181
                return "QueryShortChanIDs"
1✔
182
        case MsgReplyShortChanIDsEnd:
1✔
183
                return "ReplyShortChanIDsEnd"
1✔
184
        case MsgQueryChannelRange:
1✔
185
                return "QueryChannelRange"
1✔
186
        case MsgReplyChannelRange:
1✔
187
                return "ReplyChannelRange"
1✔
188
        case MsgGossipTimestampRange:
1✔
189
                return "GossipTimestampRange"
1✔
190
        case MsgClosingComplete:
1✔
191
                return "ClosingComplete"
1✔
192
        case MsgClosingSig:
1✔
193
                return "ClosingSig"
1✔
194
        case MsgAnnounceSignatures2:
1✔
195
                return "MsgAnnounceSignatures2"
1✔
196
        case MsgChannelAnnouncement2:
1✔
197
                return "ChannelAnnouncement2"
1✔
198
        case MsgNodeAnnouncement2:
1✔
199
                return "NodeAnnouncement2"
1✔
200
        case MsgChannelUpdate2:
1✔
201
                return "ChannelUpdate2"
1✔
202
        case MsgOnionMessage:
1✔
203
                return "OnionMessage"
1✔
204
        default:
×
205
                return "<unknown>"
×
206
        }
207
}
208

209
// UnknownMessage is an implementation of the error interface that allows the
210
// creation of an error in response to an unknown message.
211
type UnknownMessage struct {
212
        messageType MessageType
213
}
214

215
// Error returns a human readable string describing the error.
216
//
217
// This is part of the error interface.
218
func (u *UnknownMessage) Error() string {
×
219
        return fmt.Sprintf("unable to parse message of unknown type: %v",
×
220
                u.messageType)
×
221
}
×
222

223
// Serializable is an interface which defines a lightning wire serializable
224
// object.
225
type Serializable interface {
226
        // Decode reads the bytes stream and converts it to the object.
227
        Decode(io.Reader, uint32) error
228

229
        // Encode converts object to the bytes stream and write it into the
230
        // write buffer.
231
        Encode(*bytes.Buffer, uint32) error
232
}
233

234
// Message is an interface that defines a lightning wire protocol message. The
235
// interface is general in order to allow implementing types full control over
236
// the representation of its data.
237
type Message interface {
238
        Serializable
239
        MsgType() MessageType
240
}
241

242
// LinkUpdater is an interface implemented by most messages in BOLT 2 that are
243
// allowed to update the channel state.
244
type LinkUpdater interface {
245
        // All LinkUpdater messages are messages and so we embed the interface
246
        // so that we can treat it as a message if all we know about it is that
247
        // it is a LinkUpdater message.
248
        Message
249

250
        // TargetChanID returns the channel id of the link for which this
251
        // message is intended.
252
        TargetChanID() ChannelID
253
}
254

255
// SizeableMessage is an interface that extends the base Message interface with
256
// a method to calculate the serialized size of a message.
257
type SizeableMessage interface {
258
        Message
259

260
        // SerializedSize returns the serialized size of the message in bytes.
261
        // The returned size includes the message type header bytes.
262
        SerializedSize() (uint32, error)
263
}
264

265
// MessageSerializedSize calculates the serialized size of a message in bytes.
266
// This is a helper function that can be used by all message types to implement
267
// the SerializedSize method.
268
func MessageSerializedSize(msg Message) (uint32, error) {
197✔
269
        var buf bytes.Buffer
197✔
270

197✔
271
        // Encode the message to the buffer.
197✔
272
        if err := msg.Encode(&buf, 0); err != nil {
201✔
273
                return 0, err
4✔
274
        }
4✔
275

276
        // Add the size of the message type.
277
        return uint32(buf.Len()) + MessageTypeSize, nil
193✔
278
}
279

280
// makeEmptyMessage creates a new empty message of the proper concrete type
281
// based on the passed message type.
282
func makeEmptyMessage(msgType MessageType) (Message, error) {
20,412✔
283
        var msg Message
20,412✔
284

20,412✔
285
        switch msgType {
20,412✔
286
        case MsgWarning:
224✔
287
                msg = &Warning{}
224✔
288
        case MsgStfu:
237✔
289
                msg = &Stfu{}
237✔
290
        case MsgInit:
263✔
291
                msg = &Init{}
263✔
292
        case MsgOpenChannel:
368✔
293
                msg = &OpenChannel{}
368✔
294
        case MsgAcceptChannel:
335✔
295
                msg = &AcceptChannel{}
335✔
296
        case MsgFundingCreated:
274✔
297
                msg = &FundingCreated{}
274✔
298
        case MsgFundingSigned:
269✔
299
                msg = &FundingSigned{}
269✔
300
        case MsgChannelReady:
295✔
301
                msg = &ChannelReady{}
295✔
302
        case MsgShutdown:
286✔
303
                msg = &Shutdown{}
286✔
304
        case MsgClosingSigned:
274✔
305
                msg = &ClosingSigned{}
274✔
306
        case MsgDynPropose:
369✔
307
                msg = &DynPropose{}
369✔
308
        case MsgDynAck:
304✔
309
                msg = &DynAck{}
304✔
310
        case MsgDynReject:
260✔
311
                msg = &DynReject{}
260✔
312
        case MsgDynCommit:
287✔
313
                msg = &DynCommit{}
287✔
314
        case MsgKickoffSig:
230✔
315
                msg = &KickoffSig{}
230✔
316
        case MsgUpdateAddHTLC:
2,456✔
317
                msg = &UpdateAddHTLC{}
2,456✔
318
        case MsgUpdateFailHTLC:
671✔
319
                msg = &UpdateFailHTLC{}
671✔
320
        case MsgUpdateFulfillHTLC:
1,240✔
321
                msg = &UpdateFulfillHTLC{}
1,240✔
322
        case MsgCommitSig:
2,434✔
323
                msg = &CommitSig{}
2,434✔
324
        case MsgRevokeAndAck:
264✔
325
                msg = &RevokeAndAck{}
264✔
326
        case MsgUpdateFee:
304✔
327
                msg = &UpdateFee{}
304✔
328
        case MsgUpdateFailMalformedHTLC:
236✔
329
                msg = &UpdateFailMalformedHTLC{}
236✔
330
        case MsgChannelReestablish:
277✔
331
                msg = &ChannelReestablish{}
277✔
332
        case MsgError:
215✔
333
                msg = &Error{}
215✔
334
        case MsgChannelAnnouncement:
250✔
335
                msg = &ChannelAnnouncement1{}
250✔
336
        case MsgChannelUpdate:
265✔
337
                msg = &ChannelUpdate1{}
265✔
338
        case MsgNodeAnnouncement:
593✔
339
                msg = &NodeAnnouncement1{}
593✔
340
        case MsgPing:
213✔
341
                msg = &Ping{}
213✔
342
        case MsgAnnounceSignatures:
229✔
343
                msg = &AnnounceSignatures1{}
229✔
344
        case MsgPong:
210✔
345
                msg = &Pong{}
210✔
346
        case MsgQueryShortChanIDs:
1,258✔
347
                msg = &QueryShortChanIDs{}
1,258✔
348
        case MsgReplyShortChanIDsEnd:
231✔
349
                msg = &ReplyShortChanIDsEnd{}
231✔
350
        case MsgQueryChannelRange:
300✔
351
                msg = &QueryChannelRange{}
300✔
352
        case MsgReplyChannelRange:
1,317✔
353
                msg = &ReplyChannelRange{}
1,317✔
354
        case MsgGossipTimestampRange:
278✔
355
                msg = &GossipTimestampRange{}
278✔
356
        case MsgClosingComplete:
291✔
357
                msg = &ClosingComplete{}
291✔
358
        case MsgClosingSig:
278✔
359
                msg = &ClosingSig{}
278✔
360
        case MsgAnnounceSignatures2:
282✔
361
                msg = &AnnounceSignatures2{}
282✔
362
        case MsgChannelAnnouncement2:
352✔
363
                msg = &ChannelAnnouncement2{}
352✔
364
        case MsgNodeAnnouncement2:
324✔
365
                msg = &NodeAnnouncement2{}
324✔
366
        case MsgChannelUpdate2:
339✔
367
                msg = &ChannelUpdate2{}
339✔
368
        case MsgOnionMessage:
201✔
369
                msg = &OnionMessage{}
201✔
370
        default:
829✔
371
                // If the message is not within our custom range and has not
829✔
372
                // specifically been overridden, return an unknown message.
829✔
373
                //
829✔
374
                // Note that we do not allow custom message overrides to replace
829✔
375
                // known message types, only protocol messages that are not yet
829✔
376
                // known to lnd.
829✔
377
                if msgType < CustomTypeStart && !IsCustomOverride(msgType) {
1,638✔
378
                        return nil, &UnknownMessage{msgType}
809✔
379
                }
809✔
380

381
                msg = &Custom{
20✔
382
                        Type: msgType,
20✔
383
                }
20✔
384
        }
385

386
        return msg, nil
19,603✔
387
}
388

389
// MakeEmptyMessage creates a new empty message of the proper concrete type
390
// based on the passed message type. This is exported to be used in tests.
391
func MakeEmptyMessage(msgType MessageType) (Message, error) {
5,078✔
392
        return makeEmptyMessage(msgType)
5,078✔
393
}
5,078✔
394

395
// WriteMessage writes a lightning Message to a buffer including the necessary
396
// header information and returns the number of bytes written. If any error is
397
// encountered, the buffer passed will be reset to its original state since we
398
// don't want any broken bytes left. In other words, no bytes will be written
399
// if there's an error. Either all or none of the message bytes will be written
400
// to the buffer.
401
//
402
// NOTE: this method is not concurrent safe.
403
func WriteMessage(buf *bytes.Buffer, msg Message, pver uint32) (int, error) {
13,502✔
404
        // Record the size of the bytes already written in buffer.
13,502✔
405
        oldByteSize := buf.Len()
13,502✔
406

13,502✔
407
        // cleanBrokenBytes is a helper closure that helps reset the buffer to
13,502✔
408
        // its original state. It truncates all the bytes written in current
13,502✔
409
        // scope.
13,502✔
410
        var cleanBrokenBytes = func(b *bytes.Buffer) int {
13,506✔
411
                b.Truncate(oldByteSize)
4✔
412
                return 0
4✔
413
        }
4✔
414

415
        // Write the message type.
416
        var mType [2]byte
13,502✔
417
        binary.BigEndian.PutUint16(mType[:], uint16(msg.MsgType()))
13,502✔
418
        msgTypeBytes, err := buf.Write(mType[:])
13,502✔
419
        if err != nil {
13,502✔
420
                return cleanBrokenBytes(buf), ErrorWriteMessageType(err)
×
421
        }
×
422

423
        // Use the write buffer to encode our message.
424
        if err := msg.Encode(buf, pver); err != nil {
13,505✔
425
                return cleanBrokenBytes(buf), ErrorEncodeMessage(err)
3✔
426
        }
3✔
427

428
        // Enforce maximum overall message payload. The write buffer now has
429
        // the size of len(originalBytes) + len(payload) + len(type). We want
430
        // to enforce the payload here, so we subtract it by the length of the
431
        // type and old bytes.
432
        lenp := buf.Len() - oldByteSize - msgTypeBytes
13,499✔
433
        if lenp > MaxMsgBody {
13,500✔
434
                return cleanBrokenBytes(buf), ErrorPayloadTooLarge(lenp)
1✔
435
        }
1✔
436

437
        return buf.Len() - oldByteSize, nil
13,498✔
438
}
439

440
// ReadMessage reads, validates, and parses the next Lightning message from r
441
// for the provided protocol version.
442
func ReadMessage(r io.Reader, pver uint32) (Message, error) {
15,333✔
443
        // First, we'll read out the first two bytes of the message so we can
15,333✔
444
        // create the proper empty message.
15,333✔
445
        var mType [2]byte
15,333✔
446
        if _, err := io.ReadFull(r, mType[:]); err != nil {
15,333✔
447
                return nil, err
×
448
        }
×
449

450
        msgType := MessageType(binary.BigEndian.Uint16(mType[:]))
15,333✔
451

15,333✔
452
        // Now that we know the target message type, we can create the proper
15,333✔
453
        // empty message type and decode the message into it.
15,333✔
454
        msg, err := makeEmptyMessage(msgType)
15,333✔
455
        if err != nil {
15,333✔
456
                return nil, err
×
457
        }
×
458
        if err := msg.Decode(r, pver); err != nil {
17,750✔
459
                return nil, err
2,417✔
460
        }
2,417✔
461

462
        return msg, nil
12,916✔
463
}
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