lnwire+peer: introduce new error for unknown message type for forward compat

This commit adds a new error type to the `lnwire` package:
`UnknownMessage`. With this error we can catch the particular case of a
an error during reading that encounters a new or unknown message. When
we encounter this message in the peer’s readHandler, we can now
gracefully handle it by just skipping to the next message rather than
closing out the section entirely.

This puts us a bit closer to the spec, but not exactly as it has an
additional constraint that we can only ignore a new message if it has
an odd type. In a future release, we’ll modify this code to match the
spec as written.
This commit is contained in:
Olaoluwa Osuntokun 2017-01-16 18:03:34 -08:00
parent 6405b1c8b3
commit f82d957c90
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
2 changed files with 32 additions and 3 deletions

View File

@ -57,6 +57,20 @@ const (
CmdPong = uint32(6010)
)
// UnknownMessage is an implementation of the error interface that allows the
// creation of an error in response to an unknown message.
type UnknownMessage struct {
messageType uint32
}
// Error returns a human readable string describing the error.
//
// This is part of the error interface.
func (u *UnknownMessage) Error() string {
return fmt.Sprintf("unable to parse message of unknown type: %v",
u.messageType)
}
// Message is an interface that defines a lightning wire protocol message. The
// interface is general in order to allow implementing types full control over
// the representation of its data.
@ -267,8 +281,9 @@ func ReadMessage(r io.Reader, pver uint32, btcnet wire.BitcoinNet) (int, Message
msg, err := makeEmptyMessage(command)
if err != nil {
discardInput(r, hdr.length)
return totalBytes, nil, nil, fmt.Errorf("ReadMessage %s",
err.Error())
return totalBytes, nil, nil, &UnknownMessage{
messageType: command,
}
}
// Check for maximum length based on the message type.

16
peer.go
View File

@ -360,7 +360,21 @@ out:
nextMsg, _, err := p.readNextMessage()
if err != nil {
peerLog.Infof("unable to read message: %v", err)
break out
switch err.(type) {
// If this is just a message we don't yet recognize,
// we'll continue processing as normal as this allows
// us to introduce new messages in a forwards
// compatible manner.
case *lnwire.UnknownMessage:
continue
// If the error we encountered wasn't just a message we
// didn't recognize, then we'll stop all processing s
// this is a fatal error.
default:
break out
}
}
var isChanUpdate bool