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

lightningnetwork / lnd / 15736109134

18 Jun 2025 02:46PM UTC coverage: 58.197% (-10.1%) from 68.248%
15736109134

Pull #9752

github

web-flow
Merge d2634a68c into 31c74f20f
Pull Request #9752: routerrpc: reject payment to invoice that don't have payment secret or blinded paths

6 of 13 new or added lines in 2 files covered. (46.15%)

28331 existing lines in 455 files now uncovered.

97860 of 168153 relevant lines covered (58.2%)

1.81 hits per line

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

73.2
/watchtower/wtwire/message.go
1
package wtwire
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "io"
8
)
9

10
// MaxMessagePayload is the maximum bytes a message can be regardless of other
11
// individual limits imposed by messages themselves.
12
const MaxMessagePayload = 65535 // 65KB
13

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

21
// The currently defined message types within this current version of the
22
// Watchtower protocol.
23
const (
24
        // MsgInit identifies an encoded Init message.
25
        MsgInit MessageType = 600
26

27
        // MsgError identifies an encoded Error message.
28
        MsgError MessageType = 601
29

30
        // MsgCreateSession identifies an encoded CreateSession message.
31
        MsgCreateSession MessageType = 602
32

33
        // MsgCreateSessionReply identifies an encoded CreateSessionReply message.
34
        MsgCreateSessionReply MessageType = 603
35

36
        // MsgStateUpdate identifies an encoded StateUpdate message.
37
        MsgStateUpdate MessageType = 604
38

39
        // MsgStateUpdateReply identifies an encoded StateUpdateReply message.
40
        MsgStateUpdateReply MessageType = 605
41

42
        // MsgDeleteSession identifies an encoded DeleteSession message.
43
        MsgDeleteSession MessageType = 606
44

45
        // MsgDeleteSessionReply identifies an encoded DeleteSessionReply
46
        // message.
47
        MsgDeleteSessionReply MessageType = 607
48
)
49

50
// String returns a human readable description of the message type.
51
func (m MessageType) String() string {
3✔
52
        switch m {
3✔
53
        case MsgInit:
3✔
54
                return "Init"
3✔
55
        case MsgCreateSession:
3✔
56
                return "MsgCreateSession"
3✔
57
        case MsgCreateSessionReply:
3✔
58
                return "MsgCreateSessionReply"
3✔
59
        case MsgStateUpdate:
3✔
60
                return "MsgStateUpdate"
3✔
61
        case MsgStateUpdateReply:
3✔
62
                return "MsgStateUpdateReply"
3✔
63
        case MsgDeleteSession:
3✔
64
                return "MsgDeleteSession"
3✔
65
        case MsgDeleteSessionReply:
3✔
66
                return "MsgDeleteSessionReply"
3✔
UNCOV
67
        case MsgError:
×
UNCOV
68
                return "Error"
×
69
        default:
×
70
                return "<unknown>"
×
71
        }
72
}
73

74
// Serializable is an interface which defines a lightning wire serializable
75
// object.
76
type Serializable interface {
77
        // Decode reads the bytes stream and converts it to the object.
78
        Decode(io.Reader, uint32) error
79

80
        // Encode converts object to the bytes stream and write it into the
81
        // write buffer.
82
        Encode(io.Writer, uint32) error
83
}
84

85
// Message is an interface that defines a lightning wire protocol message. The
86
// interface is general in order to allow implementing types full control over
87
// the representation of its data.
88
type Message interface {
89
        Serializable
90

91
        // MsgType returns a MessageType that uniquely identifies the message to
92
        // be encoded.
93
        MsgType() MessageType
94

95
        // MaxPayloadLength is the maximum serialized length that a particular
96
        // message type can take.
97
        MaxPayloadLength(uint32) uint32
98
}
99

100
// makeEmptyMessage creates a new empty message of the proper concrete type
101
// based on the passed message type.
102
func makeEmptyMessage(msgType MessageType) (Message, error) {
3✔
103
        var msg Message
3✔
104

3✔
105
        switch msgType {
3✔
106
        case MsgInit:
3✔
107
                msg = &Init{}
3✔
108
        case MsgCreateSession:
3✔
109
                msg = &CreateSession{}
3✔
110
        case MsgCreateSessionReply:
3✔
111
                msg = &CreateSessionReply{}
3✔
112
        case MsgStateUpdate:
3✔
113
                msg = &StateUpdate{}
3✔
114
        case MsgStateUpdateReply:
3✔
115
                msg = &StateUpdateReply{}
3✔
116
        case MsgDeleteSession:
3✔
117
                msg = &DeleteSession{}
3✔
118
        case MsgDeleteSessionReply:
3✔
119
                msg = &DeleteSessionReply{}
3✔
UNCOV
120
        case MsgError:
×
UNCOV
121
                msg = &Error{}
×
122
        default:
×
123
                return nil, fmt.Errorf("unknown message type [%d]", msgType)
×
124
        }
125

126
        return msg, nil
3✔
127
}
128

129
// WriteMessage writes a lightning Message to w including the necessary header
130
// information and returns the number of bytes written.
131
func WriteMessage(w io.Writer, msg Message, pver uint32) (int, error) {
3✔
132
        totalBytes := 0
3✔
133

3✔
134
        // Encode the message payload itself into a temporary buffer.
3✔
135
        // TODO(roasbeef): create buffer pool
3✔
136
        var bw bytes.Buffer
3✔
137
        if err := msg.Encode(&bw, pver); err != nil {
3✔
138
                return totalBytes, err
×
139
        }
×
140
        payload := bw.Bytes()
3✔
141
        lenp := len(payload)
3✔
142

3✔
143
        // Enforce maximum overall message payload.
3✔
144
        if lenp > MaxMessagePayload {
3✔
145
                return totalBytes, fmt.Errorf("message payload is too large - "+
×
146
                        "encoded %d bytes, but maximum message payload is %d bytes",
×
147
                        lenp, MaxMessagePayload)
×
148
        }
×
149

150
        // Enforce maximum message payload on the message type.
151
        mpl := msg.MaxPayloadLength(pver)
3✔
152
        if uint32(lenp) > mpl {
3✔
153
                return totalBytes, fmt.Errorf("message payload is too large - "+
×
154
                        "encoded %d bytes, but maximum message payload of "+
×
155
                        "type %v is %d bytes", lenp, msg.MsgType(), mpl)
×
156
        }
×
157

158
        // With the initial sanity checks complete, we'll now write out the
159
        // message type itself.
160
        var mType [2]byte
3✔
161
        binary.BigEndian.PutUint16(mType[:], uint16(msg.MsgType()))
3✔
162
        n, err := w.Write(mType[:])
3✔
163
        totalBytes += n
3✔
164
        if err != nil {
3✔
165
                return totalBytes, err
×
166
        }
×
167

168
        // With the message type written, we'll now write out the raw payload
169
        // itself.
170
        n, err = w.Write(payload)
3✔
171
        totalBytes += n
3✔
172

3✔
173
        return totalBytes, err
3✔
174
}
175

176
// ReadMessage reads, validates, and parses the next Watchtower message from r
177
// for the provided protocol version.
178
func ReadMessage(r io.Reader, pver uint32) (Message, error) {
3✔
179
        // First, we'll read out the first two bytes of the message so we can
3✔
180
        // create the proper empty message.
3✔
181
        var mType [2]byte
3✔
182
        if _, err := io.ReadFull(r, mType[:]); err != nil {
3✔
183
                return nil, err
×
184
        }
×
185

186
        msgType := MessageType(binary.BigEndian.Uint16(mType[:]))
3✔
187

3✔
188
        // Now that we know the target message type, we can create the proper
3✔
189
        // empty message type and decode the message into it.
3✔
190
        msg, err := makeEmptyMessage(msgType)
3✔
191
        if err != nil {
3✔
192
                return nil, err
×
193
        }
×
194
        if err := msg.Decode(r, pver); err != nil {
3✔
UNCOV
195
                return nil, err
×
UNCOV
196
        }
×
197

198
        return msg, nil
3✔
199
}
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