2016-12-07 18:46:22 +03:00
|
|
|
package lnwire
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2017-08-21 22:40:29 -07:00
|
|
|
"fmt"
|
2017-12-02 18:23:05 -08:00
|
|
|
"image/color"
|
2016-12-22 12:24:48 -08:00
|
|
|
"io"
|
|
|
|
"net"
|
2017-08-21 22:40:29 -07:00
|
|
|
"unicode/utf8"
|
2016-12-07 18:46:22 +03:00
|
|
|
)
|
|
|
|
|
2018-03-23 15:46:04 -07:00
|
|
|
// ErrUnknownAddrType is an error returned if we encounter an unknown address type
|
|
|
|
// when parsing addresses.
|
|
|
|
type ErrUnknownAddrType struct {
|
|
|
|
addrType addressType
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error returns a human readable string describing the error.
|
|
|
|
//
|
|
|
|
// NOTE: implements the error interface.
|
|
|
|
func (e ErrUnknownAddrType) Error() string {
|
|
|
|
return fmt.Sprintf("unknown address type: %v", e.addrType)
|
|
|
|
}
|
|
|
|
|
2019-01-03 20:52:03 -08:00
|
|
|
// ErrInvalidNodeAlias is an error returned if a node alias we parse on the
|
|
|
|
// wire is invalid, as in it has non UTF-8 characters.
|
|
|
|
type ErrInvalidNodeAlias struct{}
|
|
|
|
|
|
|
|
// Error returns a human readable string describing the error.
|
|
|
|
//
|
|
|
|
// NOTE: implements the error interface.
|
|
|
|
func (e ErrInvalidNodeAlias) Error() string {
|
|
|
|
return "node alias has non-utf8 characters"
|
|
|
|
}
|
|
|
|
|
2020-11-26 05:12:29 +08:00
|
|
|
// NodeAlias is 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.
|
2017-08-21 22:40:29 -07:00
|
|
|
type NodeAlias [32]byte
|
2016-12-24 16:55:31 -06:00
|
|
|
|
2017-08-21 22:40:29 -07: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-24 16:55:31 -06:00
|
|
|
|
2017-08-21 22:40:29 -07:00
|
|
|
if len(s) > 32 {
|
2019-01-03 20:52:03 -08:00
|
|
|
return n, fmt.Errorf("alias too large: max is %v, got %v", 32,
|
|
|
|
len(s))
|
2017-03-08 14:21:50 -08:00
|
|
|
}
|
|
|
|
|
2017-08-21 22:40:29 -07:00
|
|
|
if !utf8.ValidString(s) {
|
2019-01-03 20:52:03 -08:00
|
|
|
return n, &ErrInvalidNodeAlias{}
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-08-21 22:40:29 -07:00
|
|
|
copy(n[:], []byte(s))
|
|
|
|
return n, nil
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-08-21 22:40:29 -07:00
|
|
|
// String returns a utf8 string representation of the alias bytes.
|
|
|
|
func (n NodeAlias) String() string {
|
2017-12-15 17:02:04 -06:00
|
|
|
// Trim trailing zero-bytes for presentation
|
|
|
|
return string(bytes.Trim(n[:], "\x00"))
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-03-05 22:43:34 -06: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.
|
2018-01-30 19:41:52 -08:00
|
|
|
Signature Sig
|
2016-12-07 18:46:22 +03:00
|
|
|
|
2017-08-21 22:42:50 -07:00
|
|
|
// Features is the list of protocol features this node supports.
|
2017-10-11 11:37:54 -07:00
|
|
|
Features *RawFeatureVector
|
2017-08-21 22:42:50 -07:00
|
|
|
|
|
|
|
// Timestamp allows ordering in the case of multiple announcements.
|
2016-12-07 18:46:22 +03:00
|
|
|
Timestamp uint32
|
|
|
|
|
2017-02-17 01:29:23 -08:00
|
|
|
// NodeID is a public key which is used as node identification.
|
2018-01-30 19:53:49 -08:00
|
|
|
NodeID [33]byte
|
2016-12-07 18:46:22 +03:00
|
|
|
|
2017-08-21 22:42:50 -07:00
|
|
|
// RGBColor is used to customize their node's appearance in maps and
|
|
|
|
// graphs
|
2017-12-02 18:23:05 -08:00
|
|
|
RGBColor color.RGBA
|
2016-12-07 18:46:22 +03:00
|
|
|
|
2017-08-21 22:40:29 -07:00
|
|
|
// Alias is used to customize their node's appearance in maps and
|
|
|
|
// graphs
|
|
|
|
Alias NodeAlias
|
2017-03-20 02:24:55 -07:00
|
|
|
|
2017-08-21 22:42:50 -07:00
|
|
|
// Address includes two specification fields: 'ipv6' and 'port' on
|
|
|
|
// which the node is accepting incoming connections.
|
2017-02-17 01:29:23 -08:00
|
|
|
Addresses []net.Addr
|
2018-08-31 19:33:05 -07:00
|
|
|
|
|
|
|
// ExtraOpaqueData is the set of data that was appended to this
|
|
|
|
// message, some of which we may not actually know how to iterate or
|
|
|
|
// parse. By holding onto this data, we ensure that we're able to
|
|
|
|
// properly validate the set of signatures that cover these new fields,
|
|
|
|
// and ensure we're able to make upgrades to the network in a forwards
|
|
|
|
// compatible manner.
|
2020-01-27 17:25:36 -08:00
|
|
|
ExtraOpaqueData ExtraOpaqueData
|
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-05 22:43:34 -06: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 {
|
2020-01-27 17:25:36 -08:00
|
|
|
return ReadElements(r,
|
2017-02-23 22:56:47 +03:00
|
|
|
&a.Signature,
|
2017-08-21 22:42:50 -07:00
|
|
|
&a.Features,
|
2017-02-23 22:56:47 +03:00
|
|
|
&a.Timestamp,
|
|
|
|
&a.NodeID,
|
|
|
|
&a.RGBColor,
|
2019-01-03 20:52:03 -08:00
|
|
|
&a.Alias,
|
2017-05-12 14:30:10 -07:00
|
|
|
&a.Addresses,
|
2020-01-27 17:25:36 -08:00
|
|
|
&a.ExtraOpaqueData,
|
2016-12-07 18:46:22 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2017-03-05 22:43:34 -06:00
|
|
|
// Encode serializes the target NodeAnnouncement into the passed io.Writer
|
|
|
|
// observing the protocol version specified.
|
2016-12-07 18:46:22 +03:00
|
|
|
//
|
2021-06-18 15:11:43 +08:00
|
|
|
// This is part of the lnwire.Message interface.
|
2021-06-17 14:17:30 +08:00
|
|
|
func (a *NodeAnnouncement) Encode(w *bytes.Buffer, pver uint32) error {
|
2021-06-18 15:11:43 +08:00
|
|
|
if err := WriteSig(w, a.Signature); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteRawFeatureVector(w, a.Features); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteUint32(w, a.Timestamp); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteBytes(w, a.NodeID[:]); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteColorRGBA(w, a.RGBColor); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteNodeAlias(w, a.Alias); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteNetAddrs(w, a.Addresses); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return WriteBytes(w, a.ExtraOpaqueData)
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|
|
|
|
|
2017-04-19 15:57:43 -07: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-19 15:57:43 -07:00
|
|
|
func (a *NodeAnnouncement) MsgType() MessageType {
|
|
|
|
return MsgNodeAnnouncement
|
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.
|
2021-06-18 15:11:43 +08:00
|
|
|
buffer := make([]byte, 0, MaxMsgBody)
|
|
|
|
buf := bytes.NewBuffer(buffer)
|
|
|
|
|
|
|
|
if err := WriteRawFeatureVector(buf, a.Features); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteUint32(buf, a.Timestamp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteBytes(buf, a.NodeID[:]); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteColorRGBA(buf, a.RGBColor); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteNodeAlias(buf, a.Alias); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteNetAddrs(buf, a.Addresses); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := WriteBytes(buf, a.ExtraOpaqueData); err != nil {
|
2016-12-07 18:46:22 +03:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-06-18 15:11:43 +08:00
|
|
|
return buf.Bytes(), nil
|
2016-12-07 18:46:22 +03:00
|
|
|
}
|