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

lightningnetwork / lnd / 20056621017

09 Dec 2025 08:18AM UTC coverage: 66.65%. First build
20056621017

Pull #10433

github

web-flow
Merge ad87b492d into ec480f033
Pull Request #10433: backport: graph: fix various races

16 of 20 new or added lines in 3 files covered. (80.0%)

137354 of 206082 relevant lines covered (66.65%)

21304.09 hits per line

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

87.04
/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/btcsuite/btcd/btcec/v2/ecdsa"
11
        "github.com/lightningnetwork/lnd/lnwire"
12
)
13

14
// Node represents an individual vertex/node within the channel graph.
15
// A node is connected to other nodes by one or more channel edges emanating
16
// from it. As the graph is directed, a node will also have an incoming edge
17
// attached to it for each outgoing edge.
18
type Node struct {
19
        // PubKeyBytes is the raw bytes of the public key of the target node.
20
        PubKeyBytes [33]byte
21

22
        // HaveNodeAnnouncement indicates whether we received a node
23
        // announcement for this particular node. If true, the remaining fields
24
        // will be set, if false only the PubKey is known for this node.
25
        HaveNodeAnnouncement bool
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 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 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
        // TODO(roasbeef): discovery will need storage to keep it's last IP
57
        // address and re-announce if interface changes?
58

59
        // TODO(roasbeef): add update method and fetch?
60
}
61

62
// PubKey is the node's long-term identity public key. This key will be used to
63
// authenticated any advertisements/updates sent by the node.
64
func (n *Node) PubKey() (*btcec.PublicKey, error) {
2,883✔
65
        return btcec.ParsePubKey(n.PubKeyBytes[:])
2,883✔
66
}
2,883✔
67

68
// AuthSig is a signature under the advertised public key which serves to
69
// authenticate the attributes announced by this node.
70
//
71
// NOTE: By having this method to access an attribute, we ensure we only need
72
// to fully deserialize the signature if absolutely necessary.
NEW
73
func (n *Node) AuthSig() (*ecdsa.Signature, error) {
×
NEW
74
        return ecdsa.ParseSignature(n.AuthSigBytes)
×
75
}
×
76

77
// AddPubKey is a setter-link method that can be used to swap out the public
78
// key for a node.
79
func (n *Node) AddPubKey(key *btcec.PublicKey) {
69✔
80
        copy(n.PubKeyBytes[:], key.SerializeCompressed())
69✔
81
}
69✔
82

83
// NodeAnnouncement retrieves the latest node announcement of the node.
84
func (n *Node) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement1,
85
        error) {
18✔
86

18✔
87
        if !n.HaveNodeAnnouncement {
21✔
88
                return nil, fmt.Errorf("node does not have node announcement")
3✔
89
        }
3✔
90

91
        alias, err := lnwire.NewNodeAlias(n.Alias)
18✔
92
        if err != nil {
18✔
93
                return nil, err
×
94
        }
×
95

96
        nodeAnn := &lnwire.NodeAnnouncement1{
18✔
97
                Features:        n.Features.RawFeatureVector,
18✔
98
                NodeID:          n.PubKeyBytes,
18✔
99
                RGBColor:        n.Color,
18✔
100
                Alias:           alias,
18✔
101
                Addresses:       n.Addresses,
18✔
102
                Timestamp:       uint32(n.LastUpdate.Unix()),
18✔
103
                ExtraOpaqueData: n.ExtraOpaqueData,
18✔
104
        }
18✔
105

18✔
106
        if !signed {
21✔
107
                return nodeAnn, nil
3✔
108
        }
3✔
109

110
        sig, err := lnwire.NewSigFromECDSARawSignature(n.AuthSigBytes)
18✔
111
        if err != nil {
18✔
112
                return nil, err
×
113
        }
×
114

115
        nodeAnn.Signature = sig
18✔
116

18✔
117
        return nodeAnn, nil
18✔
118
}
119

120
// NodeFromWireAnnouncement creates a Node instance from an
121
// lnwire.NodeAnnouncement1 message.
122
func NodeFromWireAnnouncement(msg *lnwire.NodeAnnouncement1) *Node {
20✔
123
        timestamp := time.Unix(int64(msg.Timestamp), 0)
20✔
124
        features := lnwire.NewFeatureVector(msg.Features, lnwire.Features)
20✔
125

20✔
126
        return &Node{
20✔
127
                HaveNodeAnnouncement: true,
20✔
128
                LastUpdate:           timestamp,
20✔
129
                Addresses:            msg.Addresses,
20✔
130
                PubKeyBytes:          msg.NodeID,
20✔
131
                Alias:                msg.Alias.String(),
20✔
132
                AuthSigBytes:         msg.Signature.ToSignatureBytes(),
20✔
133
                Features:             features,
20✔
134
                Color:                msg.RGBColor,
20✔
135
                ExtraOpaqueData:      msg.ExtraOpaqueData,
20✔
136
        }
20✔
137
}
20✔
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

© 2026 Coveralls, Inc