Since LND 0.18 we use the QueryChannelRange to get the latest update of the network. But there is potential deadlock which manifests itself when receiving the reply:
In FilterKnownChanIDs we aquire the channel.db mutex:
|
err := kvdb.Update(c.db, func(tx kvdb.RwTx) error { |
|
edges := tx.ReadBucket(edgeBucket) |
|
if edges == nil { |
|
return ErrGraphNoEdgesFound |
|
} |
|
edgeIndex := edges.NestedReadBucket(edgeIndexBucket) |
|
if edgeIndex == nil { |
|
return ErrGraphNoEdgesFound |
However this function also later want to aquire the mutex lock of ChannelGraph cacheMu:
|
case isZombie && !isStillZombie: |
|
err := c.markEdgeLive(tx, scid) |
|
if err != nil { |
|
return err |
|
func (c *ChannelGraph) markEdgeLive(tx kvdb.RwTx, chanID uint64) error { |
|
c.cacheMu.Lock() |
|
defer c.cacheMu.Unlock() |
|
|
|
dbFn := func(tx kvdb.RwTx) error { |
This causes the deadlock.
An example goroutine dump which shows this can be found here:
deadlock_7_dedup.txt
Since LND 0.18 we use the
QueryChannelRangeto get the latest update of the network. But there is potential deadlock which manifests itself when receiving the reply:In FilterKnownChanIDs we aquire the channel.db mutex:
lnd/channeldb/graph.go
Lines 2094 to 2101 in ba4021c
However this function also later want to aquire the mutex lock of
ChannelGraph cacheMu:lnd/channeldb/graph.go
Lines 2145 to 2148 in ba4021c
lnd/channeldb/graph.go
Lines 3621 to 3625 in ba4021c
This causes the deadlock.
An example goroutine dump which shows this can be found here:
deadlock_7_dedup.txt