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  }