github.com/decred/dcrlnd@v0.7.6/channeldb/migration/lnwire21/message.go (about) 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-2017 The Lightning Network Developers 5 6 package lnwire 7 8 import ( 9 "bytes" 10 "encoding/binary" 11 "fmt" 12 "io" 13 ) 14 15 // MaxMessagePayload is the maximum bytes a message can be regardless of other 16 // individual limits imposed by messages themselves. 17 const MaxMessagePayload = 65535 // 65KB 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 MsgInit MessageType = 16 30 MsgError = 17 31 MsgPing = 18 32 MsgPong = 19 33 MsgOpenChannel = 32 34 MsgAcceptChannel = 33 35 MsgFundingCreated = 34 36 MsgFundingSigned = 35 37 MsgFundingLocked = 36 38 MsgShutdown = 38 39 MsgClosingSigned = 39 40 MsgUpdateAddHTLC = 128 41 MsgUpdateFulfillHTLC = 130 42 MsgUpdateFailHTLC = 131 43 MsgCommitSig = 132 44 MsgRevokeAndAck = 133 45 MsgUpdateFee = 134 46 MsgUpdateFailMalformedHTLC = 135 47 MsgChannelReestablish = 136 48 MsgChannelAnnouncement = 256 49 MsgNodeAnnouncement = 257 50 MsgChannelUpdate = 258 51 MsgAnnounceSignatures = 259 52 MsgQueryShortChanIDs = 261 53 MsgReplyShortChanIDsEnd = 262 54 MsgQueryChannelRange = 263 55 MsgReplyChannelRange = 264 56 MsgGossipTimestampRange = 265 57 ) 58 59 // String return the string representation of message type. 60 func (t MessageType) String() string { 61 switch t { 62 case MsgInit: 63 return "Init" 64 case MsgOpenChannel: 65 return "MsgOpenChannel" 66 case MsgAcceptChannel: 67 return "MsgAcceptChannel" 68 case MsgFundingCreated: 69 return "MsgFundingCreated" 70 case MsgFundingSigned: 71 return "MsgFundingSigned" 72 case MsgFundingLocked: 73 return "FundingLocked" 74 case MsgShutdown: 75 return "Shutdown" 76 case MsgClosingSigned: 77 return "ClosingSigned" 78 case MsgUpdateAddHTLC: 79 return "UpdateAddHTLC" 80 case MsgUpdateFailHTLC: 81 return "UpdateFailHTLC" 82 case MsgUpdateFulfillHTLC: 83 return "UpdateFulfillHTLC" 84 case MsgCommitSig: 85 return "CommitSig" 86 case MsgRevokeAndAck: 87 return "RevokeAndAck" 88 case MsgUpdateFailMalformedHTLC: 89 return "UpdateFailMalformedHTLC" 90 case MsgChannelReestablish: 91 return "ChannelReestablish" 92 case MsgError: 93 return "Error" 94 case MsgChannelAnnouncement: 95 return "ChannelAnnouncement" 96 case MsgChannelUpdate: 97 return "ChannelUpdate" 98 case MsgNodeAnnouncement: 99 return "NodeAnnouncement" 100 case MsgPing: 101 return "Ping" 102 case MsgAnnounceSignatures: 103 return "AnnounceSignatures" 104 case MsgPong: 105 return "Pong" 106 case MsgUpdateFee: 107 return "UpdateFee" 108 case MsgQueryShortChanIDs: 109 return "QueryShortChanIDs" 110 case MsgReplyShortChanIDsEnd: 111 return "ReplyShortChanIDsEnd" 112 case MsgQueryChannelRange: 113 return "QueryChannelRange" 114 case MsgReplyChannelRange: 115 return "ReplyChannelRange" 116 case MsgGossipTimestampRange: 117 return "GossipTimestampRange" 118 default: 119 return "<unknown>" 120 } 121 } 122 123 // UnknownMessage is an implementation of the error interface that allows the 124 // creation of an error in response to an unknown message. 125 type UnknownMessage struct { 126 messageType MessageType 127 } 128 129 // Error returns a human readable string describing the error. 130 // 131 // This is part of the error interface. 132 func (u *UnknownMessage) Error() string { 133 return fmt.Sprintf("unable to parse message of unknown type: %v", 134 u.messageType) 135 } 136 137 // Serializable is an interface which defines a lightning wire serializable 138 // object. 139 type Serializable interface { 140 // Decode reads the bytes stream and converts it to the object. 141 Decode(io.Reader, uint32) error 142 143 // Encode converts object to the bytes stream and write it into the 144 // writer. 145 Encode(io.Writer, uint32) error 146 } 147 148 // Message is an interface that defines a lightning wire protocol message. The 149 // interface is general in order to allow implementing types full control over 150 // the representation of its data. 151 type Message interface { 152 Serializable 153 MsgType() MessageType 154 MaxPayloadLength(uint32) uint32 155 } 156 157 // makeEmptyMessage creates a new empty message of the proper concrete type 158 // based on the passed message type. 159 func makeEmptyMessage(msgType MessageType) (Message, error) { 160 var msg Message 161 162 switch msgType { 163 case MsgInit: 164 msg = &Init{} 165 case MsgOpenChannel: 166 msg = &OpenChannel{} 167 case MsgAcceptChannel: 168 msg = &AcceptChannel{} 169 case MsgFundingCreated: 170 msg = &FundingCreated{} 171 case MsgFundingSigned: 172 msg = &FundingSigned{} 173 case MsgFundingLocked: 174 msg = &FundingLocked{} 175 case MsgShutdown: 176 msg = &Shutdown{} 177 case MsgClosingSigned: 178 msg = &ClosingSigned{} 179 case MsgUpdateAddHTLC: 180 msg = &UpdateAddHTLC{} 181 case MsgUpdateFailHTLC: 182 msg = &UpdateFailHTLC{} 183 case MsgUpdateFulfillHTLC: 184 msg = &UpdateFulfillHTLC{} 185 case MsgCommitSig: 186 msg = &CommitSig{} 187 case MsgRevokeAndAck: 188 msg = &RevokeAndAck{} 189 case MsgUpdateFee: 190 msg = &UpdateFee{} 191 case MsgUpdateFailMalformedHTLC: 192 msg = &UpdateFailMalformedHTLC{} 193 case MsgChannelReestablish: 194 msg = &ChannelReestablish{} 195 case MsgError: 196 msg = &Error{} 197 case MsgChannelAnnouncement: 198 msg = &ChannelAnnouncement{} 199 case MsgChannelUpdate: 200 msg = &ChannelUpdate{} 201 case MsgNodeAnnouncement: 202 msg = &NodeAnnouncement{} 203 case MsgPing: 204 msg = &Ping{} 205 case MsgAnnounceSignatures: 206 msg = &AnnounceSignatures{} 207 case MsgPong: 208 msg = &Pong{} 209 case MsgQueryShortChanIDs: 210 msg = &QueryShortChanIDs{} 211 case MsgReplyShortChanIDsEnd: 212 msg = &ReplyShortChanIDsEnd{} 213 case MsgQueryChannelRange: 214 msg = &QueryChannelRange{} 215 case MsgReplyChannelRange: 216 msg = &ReplyChannelRange{} 217 case MsgGossipTimestampRange: 218 msg = &GossipTimestampRange{} 219 default: 220 return nil, &UnknownMessage{msgType} 221 } 222 223 return msg, nil 224 } 225 226 // WriteMessage writes a lightning Message to w including the necessary header 227 // information and returns the number of bytes written. 228 func WriteMessage(w io.Writer, msg Message, pver uint32) (int, error) { 229 totalBytes := 0 230 231 // Encode the message payload itself into a temporary buffer. 232 // TODO(roasbeef): create buffer pool 233 var bw bytes.Buffer 234 if err := msg.Encode(&bw, pver); err != nil { 235 return totalBytes, err 236 } 237 payload := bw.Bytes() 238 lenp := len(payload) 239 240 // Enforce maximum overall message payload. 241 if lenp > MaxMessagePayload { 242 return totalBytes, fmt.Errorf("message payload is too large - "+ 243 "encoded %d bytes, but maximum message payload is %d bytes", 244 lenp, MaxMessagePayload) 245 } 246 247 // Enforce maximum message payload on the message type. 248 mpl := msg.MaxPayloadLength(pver) 249 if uint32(lenp) > mpl { 250 return totalBytes, fmt.Errorf("message payload is too large - "+ 251 "encoded %d bytes, but maximum message payload of "+ 252 "type %v is %d bytes", lenp, msg.MsgType(), mpl) 253 } 254 255 // With the initial sanity checks complete, we'll now write out the 256 // message type itself. 257 var mType [2]byte 258 binary.BigEndian.PutUint16(mType[:], uint16(msg.MsgType())) 259 n, err := w.Write(mType[:]) 260 totalBytes += n 261 if err != nil { 262 return totalBytes, err 263 } 264 265 // With the message type written, we'll now write out the raw payload 266 // itself. 267 n, err = w.Write(payload) 268 totalBytes += n 269 270 return totalBytes, err 271 } 272 273 // ReadMessage reads, validates, and parses the next Lightning message from r 274 // for the provided protocol version. 275 func ReadMessage(r io.Reader, pver uint32) (Message, error) { 276 // First, we'll read out the first two bytes of the message so we can 277 // create the proper empty message. 278 var mType [2]byte 279 if _, err := io.ReadFull(r, mType[:]); err != nil { 280 return nil, err 281 } 282 283 msgType := MessageType(binary.BigEndian.Uint16(mType[:])) 284 285 // Now that we know the target message type, we can create the proper 286 // empty message type and decode the message into it. 287 msg, err := makeEmptyMessage(msgType) 288 if err != nil { 289 return nil, err 290 } 291 if err := msg.Decode(r, pver); err != nil { 292 return nil, err 293 } 294 295 return msg, nil 296 }