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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

94.16
/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
// MessageType is the unique 2 byte big-endian integer that indicates the type
16
// of message on the wire. All messages have a very simple header which
17
// consists simply of 2-byte message type. We omit a length field, and checksum
18
// as the Lightning Protocol is intended to be encapsulated within a
19
// confidential+authenticated cryptographic messaging protocol.
20
type MessageType uint16
21

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

67
// IsChannelUpdate is a filter function that discerns channel update messages
68
// from the other messages in the Lightning Network Protocol.
69
func (t MessageType) IsChannelUpdate() bool {
9,024✔
70
        switch t {
9,024✔
71
        case MsgUpdateAddHTLC:
3,012✔
72
                return true
3,012✔
73
        case MsgUpdateFulfillHTLC:
683✔
74
                return true
683✔
75
        case MsgUpdateFailHTLC:
138✔
76
                return true
138✔
77
        case MsgUpdateFailMalformedHTLC:
3✔
78
                return true
3✔
79
        case MsgUpdateFee:
3✔
80
                return true
3✔
81
        default:
5,185✔
82
                return false
5,185✔
83
        }
84
}
85

86
// ErrorEncodeMessage is used when failed to encode the message payload.
87
func ErrorEncodeMessage(err error) error {
4✔
88
        return fmt.Errorf("failed to encode message to buffer, got %w", err)
4✔
89
}
4✔
90

91
// ErrorWriteMessageType is used when failed to write the message type.
92
func ErrorWriteMessageType(err error) error {
×
93
        return fmt.Errorf("failed to write message type, got %w", err)
×
94
}
×
95

96
// ErrorPayloadTooLarge is used when the payload size exceeds the
97
// MaxMsgBody.
98
func ErrorPayloadTooLarge(size int) error {
2✔
99
        return fmt.Errorf(
2✔
100
                "message payload is too large - encoded %d bytes, "+
2✔
101
                        "but maximum message payload is %d bytes",
2✔
102
                size, MaxMsgBody,
2✔
103
        )
2✔
104
}
2✔
105

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

194
// UnknownMessage is an implementation of the error interface that allows the
195
// creation of an error in response to an unknown message.
196
type UnknownMessage struct {
197
        messageType MessageType
198
}
199

200
// Error returns a human readable string describing the error.
201
//
202
// This is part of the error interface.
UNCOV
203
func (u *UnknownMessage) Error() string {
×
UNCOV
204
        return fmt.Sprintf("unable to parse message of unknown type: %v",
×
UNCOV
205
                u.messageType)
×
UNCOV
206
}
×
207

208
// Serializable is an interface which defines a lightning wire serializable
209
// object.
210
type Serializable interface {
211
        // Decode reads the bytes stream and converts it to the object.
212
        Decode(io.Reader, uint32) error
213

214
        // Encode converts object to the bytes stream and write it into the
215
        // write buffer.
216
        Encode(*bytes.Buffer, uint32) error
217
}
218

219
// Message is an interface that defines a lightning wire protocol message. The
220
// interface is general in order to allow implementing types full control over
221
// the representation of its data.
222
type Message interface {
223
        Serializable
224
        MsgType() MessageType
225
}
226

227
// LinkUpdater is an interface implemented by most messages in BOLT 2 that are
228
// allowed to update the channel state.
229
type LinkUpdater interface {
230
        // All LinkUpdater messages are messages and so we embed the interface
231
        // so that we can treat it as a message if all we know about it is that
232
        // it is a LinkUpdater message.
233
        Message
234

235
        // TargetChanID returns the channel id of the link for which this
236
        // message is intended.
237
        TargetChanID() ChannelID
238
}
239

240
// makeEmptyMessage creates a new empty message of the proper concrete type
241
// based on the passed message type.
242
func makeEmptyMessage(msgType MessageType) (Message, error) {
22,729✔
243
        var msg Message
22,729✔
244

22,729✔
245
        switch msgType {
22,729✔
246
        case MsgWarning:
113✔
247
                msg = &Warning{}
113✔
248
        case MsgStfu:
100✔
249
                msg = &Stfu{}
100✔
250
        case MsgInit:
180✔
251
                msg = &Init{}
180✔
252
        case MsgOpenChannel:
267✔
253
                msg = &OpenChannel{}
267✔
254
        case MsgAcceptChannel:
233✔
255
                msg = &AcceptChannel{}
233✔
256
        case MsgFundingCreated:
173✔
257
                msg = &FundingCreated{}
173✔
258
        case MsgFundingSigned:
168✔
259
                msg = &FundingSigned{}
168✔
260
        case MsgChannelReady:
175✔
261
                msg = &ChannelReady{}
175✔
262
        case MsgShutdown:
185✔
263
                msg = &Shutdown{}
185✔
264
        case MsgClosingSigned:
173✔
265
                msg = &ClosingSigned{}
173✔
266
        case MsgDynPropose:
207✔
267
                msg = &DynPropose{}
207✔
268
        case MsgDynAck:
154✔
269
                msg = &DynAck{}
154✔
270
        case MsgDynReject:
159✔
271
                msg = &DynReject{}
159✔
272
        case MsgDynCommit:
100✔
273
                msg = &DynCommit{}
100✔
274
        case MsgKickoffSig:
129✔
275
                msg = &KickoffSig{}
129✔
276
        case MsgUpdateAddHTLC:
7,854✔
277
                msg = &UpdateAddHTLC{}
7,854✔
278
        case MsgUpdateFailHTLC:
570✔
279
                msg = &UpdateFailHTLC{}
570✔
280
        case MsgUpdateFulfillHTLC:
2,890✔
281
                msg = &UpdateFulfillHTLC{}
2,890✔
282
        case MsgCommitSig:
3,629✔
283
                msg = &CommitSig{}
3,629✔
284
        case MsgRevokeAndAck:
163✔
285
                msg = &RevokeAndAck{}
163✔
286
        case MsgUpdateFee:
203✔
287
                msg = &UpdateFee{}
203✔
288
        case MsgUpdateFailMalformedHTLC:
135✔
289
                msg = &UpdateFailMalformedHTLC{}
135✔
290
        case MsgChannelReestablish:
169✔
291
                msg = &ChannelReestablish{}
169✔
292
        case MsgError:
113✔
293
                msg = &Error{}
113✔
294
        case MsgChannelAnnouncement:
157✔
295
                msg = &ChannelAnnouncement1{}
157✔
296
        case MsgChannelUpdate:
147✔
297
                msg = &ChannelUpdate1{}
147✔
298
        case MsgNodeAnnouncement:
445✔
299
                msg = &NodeAnnouncement{}
445✔
300
        case MsgPing:
112✔
301
                msg = &Ping{}
112✔
302
        case MsgAnnounceSignatures:
128✔
303
                msg = &AnnounceSignatures1{}
128✔
304
        case MsgPong:
109✔
305
                msg = &Pong{}
109✔
306
        case MsgQueryShortChanIDs:
1,157✔
307
                msg = &QueryShortChanIDs{}
1,157✔
308
        case MsgReplyShortChanIDsEnd:
130✔
309
                msg = &ReplyShortChanIDsEnd{}
130✔
310
        case MsgQueryChannelRange:
121✔
311
                msg = &QueryChannelRange{}
121✔
312
        case MsgReplyChannelRange:
1,216✔
313
                msg = &ReplyChannelRange{}
1,216✔
314
        case MsgGossipTimestampRange:
120✔
315
                msg = &GossipTimestampRange{}
120✔
316
        case MsgClosingComplete:
173✔
317
                msg = &ClosingComplete{}
173✔
318
        case MsgClosingSig:
162✔
319
                msg = &ClosingSig{}
162✔
320
        case MsgAnnounceSignatures2:
100✔
321
                msg = &AnnounceSignatures2{}
100✔
322
        case MsgChannelAnnouncement2:
100✔
323
                msg = &ChannelAnnouncement2{}
100✔
324
        case MsgChannelUpdate2:
100✔
325
                msg = &ChannelUpdate2{}
100✔
326
        default:
10✔
327
                // If the message is not within our custom range and has not
10✔
328
                // specifically been overridden, return an unknown message.
10✔
329
                //
10✔
330
                // Note that we do not allow custom message overrides to replace
10✔
331
                // known message types, only protocol messages that are not yet
10✔
332
                // known to lnd.
10✔
333
                if msgType < CustomTypeStart && !IsCustomOverride(msgType) {
11✔
334
                        return nil, &UnknownMessage{msgType}
1✔
335
                }
1✔
336

337
                msg = &Custom{
9✔
338
                        Type: msgType,
9✔
339
                }
9✔
340
        }
341

342
        return msg, nil
22,728✔
343
}
344

345
// WriteMessage writes a lightning Message to a buffer including the necessary
346
// header information and returns the number of bytes written. If any error is
347
// encountered, the buffer passed will be reset to its original state since we
348
// don't want any broken bytes left. In other words, no bytes will be written
349
// if there's an error. Either all or none of the message bytes will be written
350
// to the buffer.
351
//
352
// NOTE: this method is not concurrent safe.
353
func WriteMessage(buf *bytes.Buffer, msg Message, pver uint32) (int, error) {
21,638✔
354
        // Record the size of the bytes already written in buffer.
21,638✔
355
        oldByteSize := buf.Len()
21,638✔
356

21,638✔
357
        // cleanBrokenBytes is a helper closure that helps reset the buffer to
21,638✔
358
        // its original state. It truncates all the bytes written in current
21,638✔
359
        // scope.
21,638✔
360
        var cleanBrokenBytes = func(b *bytes.Buffer) int {
21,642✔
361
                b.Truncate(oldByteSize)
4✔
362
                return 0
4✔
363
        }
4✔
364

365
        // Write the message type.
366
        var mType [2]byte
21,638✔
367
        binary.BigEndian.PutUint16(mType[:], uint16(msg.MsgType()))
21,638✔
368
        msgTypeBytes, err := buf.Write(mType[:])
21,638✔
369
        if err != nil {
21,638✔
370
                return cleanBrokenBytes(buf), ErrorWriteMessageType(err)
×
371
        }
×
372

373
        // Use the write buffer to encode our message.
374
        if err := msg.Encode(buf, pver); err != nil {
21,641✔
375
                return cleanBrokenBytes(buf), ErrorEncodeMessage(err)
3✔
376
        }
3✔
377

378
        // Enforce maximum overall message payload. The write buffer now has
379
        // the size of len(originalBytes) + len(payload) + len(type). We want
380
        // to enforce the payload here, so we subtract it by the length of the
381
        // type and old bytes.
382
        lenp := buf.Len() - oldByteSize - msgTypeBytes
21,635✔
383
        if lenp > MaxMsgBody {
21,636✔
384
                return cleanBrokenBytes(buf), ErrorPayloadTooLarge(lenp)
1✔
385
        }
1✔
386

387
        return buf.Len() - oldByteSize, nil
21,634✔
388
}
389

390
// ReadMessage reads, validates, and parses the next Lightning message from r
391
// for the provided protocol version.
392
func ReadMessage(r io.Reader, pver uint32) (Message, error) {
22,728✔
393
        // First, we'll read out the first two bytes of the message so we can
22,728✔
394
        // create the proper empty message.
22,728✔
395
        var mType [2]byte
22,728✔
396
        if _, err := io.ReadFull(r, mType[:]); err != nil {
22,728✔
397
                return nil, err
×
398
        }
×
399

400
        msgType := MessageType(binary.BigEndian.Uint16(mType[:]))
22,728✔
401

22,728✔
402
        // Now that we know the target message type, we can create the proper
22,728✔
403
        // empty message type and decode the message into it.
22,728✔
404
        msg, err := makeEmptyMessage(msgType)
22,728✔
405
        if err != nil {
22,728✔
UNCOV
406
                return nil, err
×
UNCOV
407
        }
×
408
        if err := msg.Decode(r, pver); err != nil {
24,540✔
409
                return nil, err
1,812✔
410
        }
1,812✔
411

412
        return msg, nil
20,916✔
413
}
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