Skip to content

Commit d962b14

Browse files
authored
Merge pull request #10420 from ellemouton/removePubKeyCaching
graph: fix various races
2 parents a76f22d + e68bf6c commit d962b14

File tree

4 files changed

+13
-45
lines changed

4 files changed

+13
-45
lines changed

docs/release-notes/release-notes-0.21.0.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@
3131
or key) existed. The manager now correctly regenerates both files when either
3232
is missing, preventing "file not found" errors on startup.
3333

34+
- [Fixed race conditions](https://github.com/lightningnetwork/lnd/pull/10420) in
35+
the channel graph database. The `Node.PubKey()` and
36+
`ChannelEdgeInfo.NodeKey1/NodeKey2()` methods had check-then-act races when
37+
caching parsed public keys. Additionally, `DisconnectBlockAtHeight` was
38+
accessing the reject and channel caches without proper locking. The caching
39+
has been removed from the public key parsing methods, and proper mutex
40+
protection has been added to the cache access in `DisconnectBlockAtHeight`.
41+
3442
# New Features
3543

3644
- Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868)

graph/db/models/channel_edge_info.go

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ type ChannelEdgeInfo struct {
3030

3131
// NodeKey1Bytes is the raw public key of the first node.
3232
NodeKey1Bytes [33]byte
33-
nodeKey1 *btcec.PublicKey
3433

3534
// NodeKey2Bytes is the raw public key of the first node.
3635
NodeKey2Bytes [33]byte
37-
nodeKey2 *btcec.PublicKey
3836

3937
// BitcoinKey1Bytes is the raw public key of the first node.
4038
BitcoinKey1Bytes [33]byte
@@ -78,42 +76,16 @@ type ChannelEdgeInfo struct {
7876
// the creation of this channel. A node is considered "first" if the
7977
// lexicographical ordering the its serialized public key is "smaller" than
8078
// that of the other node involved in channel creation.
81-
//
82-
// NOTE: By having this method to access an attribute, we ensure we only need
83-
// to fully deserialize the pubkey if absolutely necessary.
8479
func (c *ChannelEdgeInfo) NodeKey1() (*btcec.PublicKey, error) {
85-
if c.nodeKey1 != nil {
86-
return c.nodeKey1, nil
87-
}
88-
89-
key, err := btcec.ParsePubKey(c.NodeKey1Bytes[:])
90-
if err != nil {
91-
return nil, err
92-
}
93-
c.nodeKey1 = key
94-
95-
return key, nil
80+
return btcec.ParsePubKey(c.NodeKey1Bytes[:])
9681
}
9782

9883
// NodeKey2 is the identity public key of the "second" node that was involved in
9984
// the creation of this channel. A node is considered "second" if the
10085
// lexicographical ordering the its serialized public key is "larger" than that
10186
// of the other node involved in channel creation.
102-
//
103-
// NOTE: By having this method to access an attribute, we ensure we only need
104-
// to fully deserialize the pubkey if absolutely necessary.
10587
func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) {
106-
if c.nodeKey2 != nil {
107-
return c.nodeKey2, nil
108-
}
109-
110-
key, err := btcec.ParsePubKey(c.NodeKey2Bytes[:])
111-
if err != nil {
112-
return nil, err
113-
}
114-
c.nodeKey2 = key
115-
116-
return key, nil
88+
return btcec.ParsePubKey(c.NodeKey2Bytes[:])
11789
}
11890

11991
// OtherNodeKeyBytes returns the node key bytes of the other end of the channel.

graph/db/models/node.go

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ type Node struct {
2222

2323
// PubKeyBytes is the raw bytes of the public key of the target node.
2424
PubKeyBytes [33]byte
25-
pubKey *btcec.PublicKey
2625

2726
// LastUpdate is the last time the vertex information for this node has
2827
// been updated.
@@ -129,21 +128,8 @@ func (n *Node) HaveAnnouncement() bool {
129128

130129
// PubKey is the node's long-term identity public key. This key will be used to
131130
// 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.
135131
func (n *Node) PubKey() (*btcec.PublicKey, error) {
136-
if n.pubKey != nil {
137-
return n.pubKey, nil
138-
}
139-
140-
key, err := btcec.ParsePubKey(n.PubKeyBytes[:])
141-
if err != nil {
142-
return nil, err
143-
}
144-
n.pubKey = key
145-
146-
return key, nil
132+
return btcec.ParsePubKey(n.PubKeyBytes[:])
147133
}
148134

149135
// NodeAnnouncement retrieves the latest node announcement of the node.

graph/db/sql_store.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,10 +2911,12 @@ func (s *SQLStore) DisconnectBlockAtHeight(height uint32) (
29112911
"height: %w", err)
29122912
}
29132913

2914+
s.cacheMu.Lock()
29142915
for _, channel := range removedChans {
29152916
s.rejectCache.remove(channel.ChannelID)
29162917
s.chanCache.remove(channel.ChannelID)
29172918
}
2919+
s.cacheMu.Unlock()
29182920

29192921
return removedChans, nil
29202922
}

0 commit comments

Comments
 (0)