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 }