2016-12-07 18:46:22 +03:00
|
|
|
package lnwire
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2017-08-22 08:40:29 +03:00
|
|
|
"fmt"
|
2016-12-22 23:24:48 +03:00
|
|
|
"io"
|
|
|
|
"net"
|
2017-08-22 08:40:29 +03:00
|
|
|
"unicode/utf8"
|
2016-12-22 23:24:48 +03:00
|
|
|
|
2016-12-07 18:46:22 +03:00
|
|
|
"github.com/roasbeef/btcd/btcec"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2017-08-22 08:40:29 +03:00
|
|
|
startPort uint16 = 1024
|
|
|
|
endPort uint16 = 49151
|
2016-12-07 18:46:22 +03:00
|
|
|
)
|
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
// RGB is used to represent the "color" of a particular node encoded as a 24
|
|
|
|
// bit value.
|
2016-12-07 18:46:22 +03:00
|
|
|
type RGB struct {
|
|
|
|
red uint8
|
|
|
|
green uint8
|
|
|
|
blue uint8
|
|
|
|
}
|
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
// NodeAlias a hex encoded UTF-8 string that may be displayed as an alternative
|
|
|
|
// to the node's ID. Notice that aliases are not unique and may be freely
|
|
|
|
// chosen by the node operators.
|
|
|
|
type NodeAlias [32]byte
|
2016-12-25 01:55:31 +03:00
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
// NewNodeAlias creates a new instance of a NodeAlias. Verification is
|
|
|
|
// performed on the passed string to ensure it meets the alias requirements.
|
|
|
|
func NewNodeAlias(s string) (NodeAlias, error) {
|
|
|
|
var n NodeAlias
|
2016-12-25 01:55:31 +03:00
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
if len(s) > 32 {
|
|
|
|
return n, fmt.Errorf("alias too large: max is %v, got %v", 32, len(s))
|
2017-03-09 01:21:50 +03:00
|
|
|
}
|
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
if !utf8.ValidString(s) {
|
|
|
|
return n, fmt.Errorf("invalid utf8 string")
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
copy(n[:], []byte(s))
|
|
|
|
return n, nil
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
// String returns a utf8 string representation of the alias bytes.
|
|
|
|
func (n NodeAlias) String() string {
|
|
|
|
return string(n[:])
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-03-06 07:43:34 +03:00
|
|
|
// NodeAnnouncement message is used to announce the presence of a Lightning
|
|
|
|
// node and also to signal that the node is accepting incoming connections.
|
|
|
|
// Each NodeAnnouncement authenticating the advertised information within the
|
|
|
|
// announcement via a signature using the advertised node pubkey.
|
2016-12-07 18:46:22 +03:00
|
|
|
type NodeAnnouncement struct {
|
|
|
|
// Signature is used to prove the ownership of node id.
|
|
|
|
Signature *btcec.Signature
|
|
|
|
|
2017-08-22 08:42:50 +03:00
|
|
|
// Features is the list of protocol features this node supports.
|
|
|
|
Features *FeatureVector
|
|
|
|
|
|
|
|
// Timestamp allows ordering in the case of multiple announcements.
|
2016-12-07 18:46:22 +03:00
|
|
|
Timestamp uint32
|
|
|
|
|
2017-02-17 12:29:23 +03:00
|
|
|
// NodeID is a public key which is used as node identification.
|
2016-12-07 18:46:22 +03:00
|
|
|
NodeID *btcec.PublicKey
|
|
|
|
|
2017-08-22 08:42:50 +03:00
|
|
|
// RGBColor is used to customize their node's appearance in maps and
|
|
|
|
// graphs
|
2016-12-07 18:46:22 +03:00
|
|
|
RGBColor RGB
|
|
|
|
|
2017-08-22 08:40:29 +03:00
|
|
|
// Alias is used to customize their node's appearance in maps and
|
|
|
|
// graphs
|
|
|
|
Alias NodeAlias
|
2017-03-20 12:24:55 +03:00
|
|
|
|
2017-08-22 08:42:50 +03:00
|
|
|
// Address includes two specification fields: 'ipv6' and 'port' on
|
|
|
|
// which the node is accepting incoming connections.
|
2017-02-17 12:29:23 +03:00
|
|
|
Addresses []net.Addr
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// A compile time check to ensure NodeAnnouncement implements the
|
|
|
|
// lnwire.Message interface.
|
|
|
|
var _ Message = (*NodeAnnouncement)(nil)
|
|
|
|
|
2017-03-06 07:43:34 +03:00
|
|
|
// Decode deserializes a serialized NodeAnnouncement stored in the passed
|
|
|
|
// io.Reader observing the specified protocol version.
|
2016-12-07 18:46:22 +03:00
|
|
|
//
|
|
|
|
// This is part of the lnwire.Message interface.
|
2017-02-23 22:56:47 +03:00
|
|
|
func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
|
2017-02-23 21:59:50 +03:00
|
|
|
return readElements(r,
|
2017-02-23 22:56:47 +03:00
|
|
|
&a.Signature,
|
2017-08-22 08:42:50 +03:00
|
|
|
&a.Features,
|
2017-02-23 22:56:47 +03:00
|
|
|
&a.Timestamp,
|
|
|
|
&a.NodeID,
|
|
|
|
&a.RGBColor,
|
2017-08-22 08:42:50 +03:00
|
|
|
a.Alias[:],
|
2017-05-13 00:30:10 +03:00
|
|
|
&a.Addresses,
|
2016-12-07 18:46:22 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2017-03-06 07:43:34 +03:00
|
|
|
// Encode serializes the target NodeAnnouncement into the passed io.Writer
|
|
|
|
// observing the protocol version specified.
|
2016-12-07 18:46:22 +03:00
|
|
|
//
|
2017-02-23 22:56:47 +03:00
|
|
|
func (a *NodeAnnouncement) Encode(w io.Writer, pver uint32) error {
|
2017-02-23 21:59:50 +03:00
|
|
|
return writeElements(w,
|
2017-02-23 22:56:47 +03:00
|
|
|
a.Signature,
|
2017-08-22 08:42:50 +03:00
|
|
|
a.Features,
|
2017-02-23 22:56:47 +03:00
|
|
|
a.Timestamp,
|
|
|
|
a.NodeID,
|
|
|
|
a.RGBColor,
|
2017-08-22 08:42:50 +03:00
|
|
|
a.Alias[:],
|
2017-05-13 00:30:10 +03:00
|
|
|
a.Addresses,
|
2016-12-07 18:46:22 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2017-04-20 01:57:43 +03:00
|
|
|
// MsgType returns the integer uniquely identifying this message type on the
|
2016-12-07 18:46:22 +03:00
|
|
|
// wire.
|
|
|
|
//
|
|
|
|
// This is part of the lnwire.Message interface.
|
2017-04-20 01:57:43 +03:00
|
|
|
func (a *NodeAnnouncement) MsgType() MessageType {
|
|
|
|
return MsgNodeAnnouncement
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// MaxPayloadLength returns the maximum allowed payload size for this message
|
|
|
|
// observing the specified protocol version.
|
|
|
|
//
|
|
|
|
// This is part of the lnwire.Message interface.
|
2017-02-23 22:56:47 +03:00
|
|
|
func (a *NodeAnnouncement) MaxPayloadLength(pver uint32) uint32 {
|
2017-04-20 02:04:38 +03:00
|
|
|
return 65533
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-02-23 22:56:47 +03:00
|
|
|
// DataToSign returns the part of the message that should be signed.
|
|
|
|
func (a *NodeAnnouncement) DataToSign() ([]byte, error) {
|
2016-12-07 18:46:22 +03:00
|
|
|
|
|
|
|
// We should not include the signatures itself.
|
|
|
|
var w bytes.Buffer
|
|
|
|
err := writeElements(&w,
|
2017-08-22 08:42:50 +03:00
|
|
|
a.Features,
|
2017-02-23 22:56:47 +03:00
|
|
|
a.Timestamp,
|
|
|
|
a.NodeID,
|
|
|
|
a.RGBColor,
|
2017-08-22 08:42:50 +03:00
|
|
|
a.Alias[:],
|
2017-05-13 00:30:10 +03:00
|
|
|
a.Addresses,
|
2016-12-07 18:46:22 +03:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-08-22 08:42:50 +03:00
|
|
|
// TODO(roasbeef): also capture the excess bytes in msg padded out?
|
|
|
|
|
2016-12-07 18:46:22 +03:00
|
|
|
return w.Bytes(), nil
|
|
|
|
}
|