github.com/decred/dcrlnd@v0.7.6/lnwire/node_announcement.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"image/color"
     7  	"io"
     8  	"net"
     9  	"unicode/utf8"
    10  )
    11  
    12  // ErrUnknownAddrType is an error returned if we encounter an unknown address
    13  // type when parsing addresses.
    14  type ErrUnknownAddrType struct {
    15  	addrType addressType
    16  }
    17  
    18  // Error returns a human readable string describing the error.
    19  //
    20  // NOTE: implements the error interface.
    21  func (e ErrUnknownAddrType) Error() string {
    22  	return fmt.Sprintf("unknown address type: %v", e.addrType)
    23  }
    24  
    25  // ErrInvalidNodeAlias is an error returned if a node alias we parse on the
    26  // wire is invalid, as in it has non UTF-8 characters.
    27  type ErrInvalidNodeAlias struct{}
    28  
    29  // Error returns a human readable string describing the error.
    30  //
    31  // NOTE: implements the error interface.
    32  func (e ErrInvalidNodeAlias) Error() string {
    33  	return "node alias has non-utf8 characters"
    34  }
    35  
    36  // NodeAlias is a hex encoded UTF-8 string that may be displayed as an
    37  // alternative to the node's ID. Notice that aliases are not unique and may be
    38  // freely chosen by the node operators.
    39  type NodeAlias [32]byte
    40  
    41  // NewNodeAlias creates a new instance of a NodeAlias. Verification is
    42  // performed on the passed string to ensure it meets the alias requirements.
    43  func NewNodeAlias(s string) (NodeAlias, error) {
    44  	var n NodeAlias
    45  
    46  	if len(s) > 32 {
    47  		return n, fmt.Errorf("alias too large: max is %v, got %v", 32,
    48  			len(s))
    49  	}
    50  
    51  	if !utf8.ValidString(s) {
    52  		return n, &ErrInvalidNodeAlias{}
    53  	}
    54  
    55  	copy(n[:], []byte(s))
    56  	return n, nil
    57  }
    58  
    59  // String returns a utf8 string representation of the alias bytes.
    60  func (n NodeAlias) String() string {
    61  	// Trim trailing zero-bytes for presentation
    62  	return string(bytes.Trim(n[:], "\x00"))
    63  }
    64  
    65  // NodeAnnouncement message is used to announce the presence of a Lightning
    66  // node and also to signal that the node is accepting incoming connections.
    67  // Each NodeAnnouncement authenticating the advertised information within the
    68  // announcement via a signature using the advertised node pubkey.
    69  type NodeAnnouncement struct {
    70  	// Signature is used to prove the ownership of node id.
    71  	Signature Sig
    72  
    73  	// Features is the list of protocol features this node supports.
    74  	Features *RawFeatureVector
    75  
    76  	// Timestamp allows ordering in the case of multiple announcements.
    77  	Timestamp uint32
    78  
    79  	// NodeID is a public key which is used as node identification.
    80  	NodeID [33]byte
    81  
    82  	// RGBColor is used to customize their node's appearance in maps and
    83  	// graphs
    84  	RGBColor color.RGBA
    85  
    86  	// Alias is used to customize their node's appearance in maps and
    87  	// graphs
    88  	Alias NodeAlias
    89  
    90  	// Address includes two specification fields: 'ipv6' and 'port' on
    91  	// which the node is accepting incoming connections.
    92  	Addresses []net.Addr
    93  
    94  	// ExtraOpaqueData is the set of data that was appended to this
    95  	// message, some of which we may not actually know how to iterate or
    96  	// parse. By holding onto this data, we ensure that we're able to
    97  	// properly validate the set of signatures that cover these new fields,
    98  	// and ensure we're able to make upgrades to the network in a forwards
    99  	// compatible manner.
   100  	ExtraOpaqueData ExtraOpaqueData
   101  }
   102  
   103  // A compile time check to ensure NodeAnnouncement implements the
   104  // lnwire.Message interface.
   105  var _ Message = (*NodeAnnouncement)(nil)
   106  
   107  // Decode deserializes a serialized NodeAnnouncement stored in the passed
   108  // io.Reader observing the specified protocol version.
   109  //
   110  // This is part of the lnwire.Message interface.
   111  func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
   112  	return ReadElements(r,
   113  		&a.Signature,
   114  		&a.Features,
   115  		&a.Timestamp,
   116  		&a.NodeID,
   117  		&a.RGBColor,
   118  		&a.Alias,
   119  		&a.Addresses,
   120  		&a.ExtraOpaqueData,
   121  	)
   122  }
   123  
   124  // Encode serializes the target NodeAnnouncement into the passed io.Writer
   125  // observing the protocol version specified.
   126  //
   127  // This is part of the lnwire.Message interface.
   128  func (a *NodeAnnouncement) Encode(w *bytes.Buffer, pver uint32) error {
   129  	if err := WriteSig(w, a.Signature); err != nil {
   130  		return err
   131  	}
   132  
   133  	if err := WriteRawFeatureVector(w, a.Features); err != nil {
   134  		return err
   135  	}
   136  
   137  	if err := WriteUint32(w, a.Timestamp); err != nil {
   138  		return err
   139  	}
   140  
   141  	if err := WriteBytes(w, a.NodeID[:]); err != nil {
   142  		return err
   143  	}
   144  
   145  	if err := WriteColorRGBA(w, a.RGBColor); err != nil {
   146  		return err
   147  	}
   148  
   149  	if err := WriteNodeAlias(w, a.Alias); err != nil {
   150  		return err
   151  	}
   152  
   153  	if err := WriteNetAddrs(w, a.Addresses); err != nil {
   154  		return err
   155  	}
   156  
   157  	return WriteBytes(w, a.ExtraOpaqueData)
   158  }
   159  
   160  // MsgType returns the integer uniquely identifying this message type on the
   161  // wire.
   162  //
   163  // This is part of the lnwire.Message interface.
   164  func (a *NodeAnnouncement) MsgType() MessageType {
   165  	return MsgNodeAnnouncement
   166  }
   167  
   168  // DataToSign returns the part of the message that should be signed.
   169  func (a *NodeAnnouncement) DataToSign() ([]byte, error) {
   170  
   171  	// We should not include the signatures itself.
   172  	buffer := make([]byte, 0, MaxMsgBody)
   173  	buf := bytes.NewBuffer(buffer)
   174  
   175  	if err := WriteRawFeatureVector(buf, a.Features); err != nil {
   176  		return nil, err
   177  	}
   178  
   179  	if err := WriteUint32(buf, a.Timestamp); err != nil {
   180  		return nil, err
   181  	}
   182  
   183  	if err := WriteBytes(buf, a.NodeID[:]); err != nil {
   184  		return nil, err
   185  	}
   186  
   187  	if err := WriteColorRGBA(buf, a.RGBColor); err != nil {
   188  		return nil, err
   189  	}
   190  
   191  	if err := WriteNodeAlias(buf, a.Alias); err != nil {
   192  		return nil, err
   193  	}
   194  
   195  	if err := WriteNetAddrs(buf, a.Addresses); err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	if err := WriteBytes(buf, a.ExtraOpaqueData); err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	return buf.Bytes(), nil
   204  }