mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
Merge pull request #5941 from bhandras/graph_cache_deadlock
channeldb: avoid locking the graph cache while iterating channels
This commit is contained in:
commit
e7e3adeb98
@ -401,10 +401,9 @@ func (c *GraphCache) UpdateChannel(info *ChannelEdgeInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
// ForEachChannel invokes the given callback for each channel of the given node.
|
||||
func (c *GraphCache) ForEachChannel(node route.Vertex,
|
||||
cb func(channel *DirectedChannel) error) error {
|
||||
|
||||
// getChannels returns a copy of the passed node's channels or nil if there
|
||||
// isn't any.
|
||||
func (c *GraphCache) getChannels(node route.Vertex) []*DirectedChannel {
|
||||
c.mtx.RLock()
|
||||
defer c.mtx.RUnlock()
|
||||
|
||||
@ -428,6 +427,8 @@ func (c *GraphCache) ForEachChannel(node route.Vertex,
|
||||
return node
|
||||
}
|
||||
|
||||
i := 0
|
||||
channelsCopy := make([]*DirectedChannel, len(channels))
|
||||
for _, channel := range channels {
|
||||
// We need to copy the channel and policy to avoid it being
|
||||
// updated in the cache if the path finding algorithm sets
|
||||
@ -439,9 +440,30 @@ func (c *GraphCache) ForEachChannel(node route.Vertex,
|
||||
channelCopy.InPolicy.ToNodeFeatures = features
|
||||
}
|
||||
|
||||
if err := cb(channelCopy); err != nil {
|
||||
channelsCopy[i] = channelCopy
|
||||
i++
|
||||
}
|
||||
|
||||
return channelsCopy
|
||||
}
|
||||
|
||||
// ForEachChannel invokes the given callback for each channel of the given node.
|
||||
func (c *GraphCache) ForEachChannel(node route.Vertex,
|
||||
cb func(channel *DirectedChannel) error) error {
|
||||
|
||||
// Obtain a copy of the node's channels. We need do this in order to
|
||||
// avoid deadlocks caused by interaction with the graph cache, channel
|
||||
// state and the graph database from multiple goroutines. This snapshot
|
||||
// is only used for path finding where being stale is acceptable since
|
||||
// the real world graph and our representation may always become
|
||||
// slightly out of sync for a short time and the actual channel state
|
||||
// is stored separately.
|
||||
channels := c.getChannels(node)
|
||||
for _, channel := range channels {
|
||||
if err := cb(channel); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -618,6 +618,9 @@ messages directly. There is no routing/path finding involved.
|
||||
* [Fixed an issue with external listeners and the `--noseedbackup` development
|
||||
flag](https://github.com/lightningnetwork/lnd/pull/5930).
|
||||
|
||||
* [Fix deadlock when using the graph cache](
|
||||
https://github.com/lightningnetwork/lnd/pull/5941)
|
||||
|
||||
## Documentation
|
||||
|
||||
The [code contribution guidelines have been updated to mention the new
|
||||
|
Loading…
Reference in New Issue
Block a user