• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 19924300449

04 Dec 2025 09:35AM UTC coverage: 53.479% (-1.9%) from 55.404%
19924300449

Pull #10419

github

web-flow
Merge f811805c6 into 20473482d
Pull Request #10419: [docs] Document use-native-sql=true for SQL migration step 2

110496 of 206616 relevant lines covered (53.48%)

21221.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.51
/graph/db/models/node.go
1
package models
2

3
import (
4
        "fmt"
5
        "image/color"
6
        "net"
7
        "time"
8

9
        "github.com/btcsuite/btcd/btcec/v2"
10
        "github.com/lightningnetwork/lnd/fn/v2"
11
        "github.com/lightningnetwork/lnd/lnwire"
12
        "github.com/lightningnetwork/lnd/routing/route"
13
)
14

15
// Node represents an individual vertex/node within the channel graph.
16
// A node is connected to other nodes by one or more channel edges emanating
17
// from it. As the graph is directed, a node will also have an incoming edge
18
// attached to it for each outgoing edge.
19
type Node struct {
20
        // Version is the gossip version that this node was advertised on.
21
        Version lnwire.GossipVersion
22

23
        // PubKeyBytes is the raw bytes of the public key of the target node.
24
        PubKeyBytes [33]byte
25
        pubKey      *btcec.PublicKey
26

27
        // LastUpdate is the last time the vertex information for this node has
28
        // been updated.
29
        LastUpdate time.Time
30

31
        // Address is the TCP address this node is reachable over.
32
        Addresses []net.Addr
33

34
        // Color is the selected color for the node.
35
        Color fn.Option[color.RGBA]
36

37
        // Alias is a nick-name for the node. The alias can be used to confirm
38
        // a node's identity or to serve as a short ID for an address book.
39
        Alias fn.Option[string]
40

41
        // AuthSigBytes is the raw signature under the advertised public key
42
        // which serves to authenticate the attributes announced by this node.
43
        AuthSigBytes []byte
44

45
        // Features is the list of protocol features supported by this node.
46
        Features *lnwire.FeatureVector
47

48
        // ExtraOpaqueData is the set of data that was appended to this
49
        // message, some of which we may not actually know how to iterate or
50
        // parse. By holding onto this data, we ensure that we're able to
51
        // properly validate the set of signatures that cover these new fields,
52
        // and ensure we're able to make upgrades to the network in a forwards
53
        // compatible manner.
54
        ExtraOpaqueData []byte
55
}
56

57
// NodeV1Fields houses the fields that are specific to a version 1 node
58
// announcement.
59
type NodeV1Fields struct {
60
        // Address is the TCP address this node is reachable over.
61
        Addresses []net.Addr
62

63
        // AuthSigBytes is the raw signature under the advertised public key
64
        // which serves to authenticate the attributes announced by this node.
65
        AuthSigBytes []byte
66

67
        // Features is the list of protocol features supported by this node.
68
        Features *lnwire.RawFeatureVector
69

70
        // Color is the selected color for the node.
71
        Color color.RGBA
72

73
        // Alias is a nick-name for the node. The alias can be used to confirm
74
        // a node's identity or to serve as a short ID for an address book.
75
        Alias string
76

77
        // LastUpdate is the last time the vertex information for this node has
78
        // been updated.
79
        LastUpdate time.Time
80

81
        // ExtraOpaqueData is the set of data that was appended to this
82
        // message, some of which we may not actually know how to iterate or
83
        // parse. By holding onto this data, we ensure that we're able to
84
        // properly validate the set of signatures that cover these new fields,
85
        // and ensure we're able to make upgrades to the network in a forwards
86
        // compatible manner.
87
        ExtraOpaqueData []byte
88
}
89

90
// NewV1Node creates a new version 1 node from the passed fields.
91
func NewV1Node(pub route.Vertex, n *NodeV1Fields) *Node {
1,130✔
92
        return &Node{
1,130✔
93
                Version:      lnwire.GossipVersion1,
1,130✔
94
                PubKeyBytes:  pub,
1,130✔
95
                Addresses:    n.Addresses,
1,130✔
96
                AuthSigBytes: n.AuthSigBytes,
1,130✔
97
                Features: lnwire.NewFeatureVector(
1,130✔
98
                        n.Features, lnwire.Features,
1,130✔
99
                ),
1,130✔
100
                Color:           fn.Some(n.Color),
1,130✔
101
                Alias:           fn.Some(n.Alias),
1,130✔
102
                LastUpdate:      n.LastUpdate,
1,130✔
103
                ExtraOpaqueData: n.ExtraOpaqueData,
1,130✔
104
        }
1,130✔
105
}
1,130✔
106

107
// NewV1ShellNode creates a new shell version 1 node.
108
func NewV1ShellNode(pubKey route.Vertex) *Node {
9,566✔
109
        return NewShellNode(lnwire.GossipVersion1, pubKey)
9,566✔
110
}
9,566✔
111

112
// NewShellNode creates a new shell node with the given gossip version and
113
// public key.
114
func NewShellNode(v lnwire.GossipVersion, pubKey route.Vertex) *Node {
9,566✔
115
        return &Node{
9,566✔
116
                Version:     v,
9,566✔
117
                PubKeyBytes: pubKey,
9,566✔
118
                Features:    lnwire.EmptyFeatureVector(),
9,566✔
119
                LastUpdate:  time.Unix(0, 0),
9,566✔
120
        }
9,566✔
121
}
9,566✔
122

123
// HaveAnnouncement returns true if we have received a node announcement for
124
// this node. We determine this by checking if we have a signature for the
125
// announcement.
126
func (n *Node) HaveAnnouncement() bool {
1,186✔
127
        return len(n.AuthSigBytes) > 0
1,186✔
128
}
1,186✔
129

130
// PubKey is the node's long-term identity public key. This key will be used to
131
// authenticated any advertisements/updates sent by the node.
132
//
133
// NOTE: By having this method to access an attribute, we ensure we only need
134
// to fully deserialize the pubkey if absolutely necessary.
135
func (n *Node) PubKey() (*btcec.PublicKey, error) {
2,889✔
136
        if n.pubKey != nil {
4,417✔
137
                return n.pubKey, nil
1,528✔
138
        }
1,528✔
139

140
        key, err := btcec.ParsePubKey(n.PubKeyBytes[:])
1,361✔
141
        if err != nil {
1,361✔
142
                return nil, err
×
143
        }
×
144
        n.pubKey = key
1,361✔
145

1,361✔
146
        return key, nil
1,361✔
147
}
148

149
// NodeAnnouncement retrieves the latest node announcement of the node.
150
func (n *Node) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement1,
151
        error) {
15✔
152

15✔
153
        // Error out if we request the signed announcement, but we don't have
15✔
154
        // a signature for this announcement.
15✔
155
        if !n.HaveAnnouncement() && signed {
15✔
156
                return nil, fmt.Errorf("node does not have node announcement")
×
157
        }
×
158

159
        alias, err := lnwire.NewNodeAlias(n.Alias.UnwrapOr(""))
15✔
160
        if err != nil {
15✔
161
                return nil, err
×
162
        }
×
163

164
        nodeAnn := &lnwire.NodeAnnouncement1{
15✔
165
                Features:        n.Features.RawFeatureVector,
15✔
166
                NodeID:          n.PubKeyBytes,
15✔
167
                RGBColor:        n.Color.UnwrapOr(color.RGBA{}),
15✔
168
                Alias:           alias,
15✔
169
                Addresses:       n.Addresses,
15✔
170
                Timestamp:       uint32(n.LastUpdate.Unix()),
15✔
171
                ExtraOpaqueData: n.ExtraOpaqueData,
15✔
172
        }
15✔
173

15✔
174
        if !signed {
15✔
175
                return nodeAnn, nil
×
176
        }
×
177

178
        sig, err := lnwire.NewSigFromECDSARawSignature(n.AuthSigBytes)
15✔
179
        if err != nil {
15✔
180
                return nil, err
×
181
        }
×
182

183
        nodeAnn.Signature = sig
15✔
184

15✔
185
        return nodeAnn, nil
15✔
186
}
187

188
// NodeFromWireAnnouncement creates a Node instance from an
189
// lnwire.NodeAnnouncement1 message.
190
func NodeFromWireAnnouncement(msg *lnwire.NodeAnnouncement1) *Node {
17✔
191
        timestamp := time.Unix(int64(msg.Timestamp), 0)
17✔
192

17✔
193
        return NewV1Node(
17✔
194
                msg.NodeID,
17✔
195
                &NodeV1Fields{
17✔
196
                        LastUpdate:      timestamp,
17✔
197
                        Addresses:       msg.Addresses,
17✔
198
                        Alias:           msg.Alias.String(),
17✔
199
                        AuthSigBytes:    msg.Signature.ToSignatureBytes(),
17✔
200
                        Features:        msg.Features,
17✔
201
                        Color:           msg.RGBColor,
17✔
202
                        ExtraOpaqueData: msg.ExtraOpaqueData,
17✔
203
                },
17✔
204
        )
17✔
205
}
17✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc