github.com/decred/dcrlnd@v0.7.6/channeldb/migration/lnwire21/node_announcement.go (about)

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