Merge pull request #10420 from ellemouton/removePubKeyCaching
graph: fix various races
This commit is contained in:
4 files changed
+13
-45
No files matched your search
@@ -31,6 +31,14 @@
|
|||||||
or key) existed. The manager now correctly regenerates both files when either
|
or key) existed. The manager now correctly regenerates both files when either
|
||||||
is missing, preventing "file not found" errors on startup.
|
is missing, preventing "file not found" errors on startup.
|
||||||
|
|
||||||
|
- [Fixed race conditions](https://github.com/lightningnetwork/lnd/pull/10420) in
|
||||||
|
the channel graph database. The `Node.PubKey()` and
|
||||||
|
`ChannelEdgeInfo.NodeKey1/NodeKey2()` methods had check-then-act races when
|
||||||
|
caching parsed public keys. Additionally, `DisconnectBlockAtHeight` was
|
||||||
|
accessing the reject and channel caches without proper locking. The caching
|
||||||
|
has been removed from the public key parsing methods, and proper mutex
|
||||||
|
protection has been added to the cache access in `DisconnectBlockAtHeight`.
|
||||||
|
|
||||||
# New Features
|
# New Features
|
||||||
|
|
||||||
- Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868)
|
- Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868)
|
||||||
|
|||||||
@@ -30,11 +30,9 @@ type ChannelEdgeInfo struct {
|
|||||||
|
|
||||||
// NodeKey1Bytes is the raw public key of the first node.
|
// NodeKey1Bytes is the raw public key of the first node.
|
||||||
NodeKey1Bytes [33]byte
|
NodeKey1Bytes [33]byte
|
||||||
nodeKey1 *btcec.PublicKey
|
|
||||||
|
|
||||||
// NodeKey2Bytes is the raw public key of the first node.
|
// NodeKey2Bytes is the raw public key of the first node.
|
||||||
NodeKey2Bytes [33]byte
|
NodeKey2Bytes [33]byte
|
||||||
nodeKey2 *btcec.PublicKey
|
|
||||||
|
|
||||||
// BitcoinKey1Bytes is the raw public key of the first node.
|
// BitcoinKey1Bytes is the raw public key of the first node.
|
||||||
BitcoinKey1Bytes [33]byte
|
BitcoinKey1Bytes [33]byte
|
||||||
@@ -78,42 +76,16 @@ type ChannelEdgeInfo struct {
|
|||||||
// the creation of this channel. A node is considered "first" if the
|
// the creation of this channel. A node is considered "first" if the
|
||||||
// lexicographical ordering the its serialized public key is "smaller" than
|
// lexicographical ordering the its serialized public key is "smaller" than
|
||||||
// that of the other node involved in channel creation.
|
// that of the other node involved in channel creation.
|
||||||
//
|
|
||||||
// NOTE: By having this method to access an attribute, we ensure we only need
|
|
||||||
// to fully deserialize the pubkey if absolutely necessary.
|
|
||||||
func (c *ChannelEdgeInfo) NodeKey1() (*btcec.PublicKey, error) {
|
func (c *ChannelEdgeInfo) NodeKey1() (*btcec.PublicKey, error) {
|
||||||
if c.nodeKey1 != nil {
|
return btcec.ParsePubKey(c.NodeKey1Bytes[:])
|
||||||
return c.nodeKey1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := btcec.ParsePubKey(c.NodeKey1Bytes[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.nodeKey1 = key
|
|
||||||
|
|
||||||
return key, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeKey2 is the identity public key of the "second" node that was involved in
|
// NodeKey2 is the identity public key of the "second" node that was involved in
|
||||||
// the creation of this channel. A node is considered "second" if the
|
// the creation of this channel. A node is considered "second" if the
|
||||||
// lexicographical ordering the its serialized public key is "larger" than that
|
// lexicographical ordering the its serialized public key is "larger" than that
|
||||||
// of the other node involved in channel creation.
|
// of the other node involved in channel creation.
|
||||||
//
|
|
||||||
// NOTE: By having this method to access an attribute, we ensure we only need
|
|
||||||
// to fully deserialize the pubkey if absolutely necessary.
|
|
||||||
func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) {
|
func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) {
|
||||||
if c.nodeKey2 != nil {
|
return btcec.ParsePubKey(c.NodeKey2Bytes[:])
|
||||||
return c.nodeKey2, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := btcec.ParsePubKey(c.NodeKey2Bytes[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.nodeKey2 = key
|
|
||||||
|
|
||||||
return key, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OtherNodeKeyBytes returns the node key bytes of the other end of the channel.
|
// OtherNodeKeyBytes returns the node key bytes of the other end of the channel.
|
||||||
|
|||||||
+1
-15
@@ -22,7 +22,6 @@ type Node struct {
|
|||||||
|
|
||||||
// PubKeyBytes is the raw bytes of the public key of the target node.
|
// PubKeyBytes is the raw bytes of the public key of the target node.
|
||||||
PubKeyBytes [33]byte
|
PubKeyBytes [33]byte
|
||||||
pubKey *btcec.PublicKey
|
|
||||||
|
|
||||||
// LastUpdate is the last time the vertex information for this node has
|
// LastUpdate is the last time the vertex information for this node has
|
||||||
// been updated.
|
// been updated.
|
||||||
@@ -129,21 +128,8 @@ func (n *Node) HaveAnnouncement() bool {
|
|||||||
|
|
||||||
// PubKey is the node's long-term identity public key. This key will be used to
|
// PubKey is the node's long-term identity public key. This key will be used to
|
||||||
// authenticated any advertisements/updates sent by the node.
|
// authenticated any advertisements/updates sent by the node.
|
||||||
//
|
|
||||||
// NOTE: By having this method to access an attribute, we ensure we only need
|
|
||||||
// to fully deserialize the pubkey if absolutely necessary.
|
|
||||||
func (n *Node) PubKey() (*btcec.PublicKey, error) {
|
func (n *Node) PubKey() (*btcec.PublicKey, error) {
|
||||||
if n.pubKey != nil {
|
return btcec.ParsePubKey(n.PubKeyBytes[:])
|
||||||
return n.pubKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := btcec.ParsePubKey(n.PubKeyBytes[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
n.pubKey = key
|
|
||||||
|
|
||||||
return key, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeAnnouncement retrieves the latest node announcement of the node.
|
// NodeAnnouncement retrieves the latest node announcement of the node.
|
||||||
|
|||||||
@@ -2911,10 +2911,12 @@ func (s *SQLStore) DisconnectBlockAtHeight(height uint32) (
|
|||||||
"height: %w", err)
|
"height: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.cacheMu.Lock()
|
||||||
for _, channel := range removedChans {
|
for _, channel := range removedChans {
|
||||||
s.rejectCache.remove(channel.ChannelID)
|
s.rejectCache.remove(channel.ChannelID)
|
||||||
s.chanCache.remove(channel.ChannelID)
|
s.chanCache.remove(channel.ChannelID)
|
||||||
}
|
}
|
||||||
|
s.cacheMu.Unlock()
|
||||||
|
|
||||||
return removedChans, nil
|
return removedChans, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user