graph/db: version ForEachNodeDirectedChannel and cacheable traversal
Add a gossip version parameter to ForEachNodeDirectedChannel on the Store interface and both DB implementations (KVStore, SQLStore). The NodeTraverser and routing.Graph interfaces remain unversioned since pathfinding operates on the merged cross-version cache view. The cache population in populateCache is updated in the same commit because it is logically atomic with the versioning changes: the graph cache is the unversioned, merged view used by pathfinding, so it must be populated with data from all gossip versions. Without this change, only v1 data would be loaded into the cache, making v2 nodes and channels invisible to pathfinding.
This commit is contained in:
6 files changed
+87
-64
No files matched your search
+34
-22
@@ -163,32 +163,41 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error {
|
||||
log.Info("Populating in-memory channel graph, this might take a " +
|
||||
"while...")
|
||||
|
||||
// TODO(elle): the cache should be populated with data from across
|
||||
// protocol versions.
|
||||
err := c.db.ForEachNodeCacheable(
|
||||
ctx, lnwire.GossipVersion1, func(node route.Vertex,
|
||||
features *lnwire.FeatureVector) error {
|
||||
for _, v := range []lnwire.GossipVersion{
|
||||
gossipV1, gossipV2,
|
||||
} {
|
||||
// TODO(elle): If we have both v1 and v2 entries for the same
|
||||
// node/channel, prefer v2 when merging.
|
||||
err := c.db.ForEachNodeCacheable(ctx, v,
|
||||
func(node route.Vertex,
|
||||
features *lnwire.FeatureVector) error {
|
||||
|
||||
c.graphCache.AddNodeFeatures(node, features)
|
||||
c.graphCache.AddNodeFeatures(node, features)
|
||||
|
||||
return nil
|
||||
}, func() {},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, func() {},
|
||||
)
|
||||
if err != nil &&
|
||||
!errors.Is(err, ErrVersionNotSupportedForKVDB) {
|
||||
|
||||
err = c.db.ForEachChannelCacheable(
|
||||
lnwire.GossipVersion1, func(info *models.CachedEdgeInfo,
|
||||
policy1, policy2 *models.CachedEdgePolicy) error {
|
||||
return err
|
||||
}
|
||||
|
||||
c.graphCache.AddChannel(info, policy1, policy2)
|
||||
err = c.db.ForEachChannelCacheable(
|
||||
v, func(info *models.CachedEdgeInfo,
|
||||
policy1,
|
||||
policy2 *models.CachedEdgePolicy) error {
|
||||
|
||||
return nil
|
||||
}, func() {},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
c.graphCache.AddChannel(info, policy1, policy2)
|
||||
|
||||
return nil
|
||||
}, func() {},
|
||||
)
|
||||
if err != nil &&
|
||||
!errors.Is(err, ErrVersionNotSupportedForKVDB) {
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Finished populating in-memory channel graph (took %v, %s)",
|
||||
@@ -214,7 +223,10 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(node route.Vertex,
|
||||
return c.graphCache.ForEachChannel(node, cb)
|
||||
}
|
||||
|
||||
return c.db.ForEachNodeDirectedChannel(node, cb, reset)
|
||||
// TODO(elle): once the no-cache path needs to support
|
||||
// pathfinding across gossip versions, this should iterate
|
||||
// across all versions rather than defaulting to v1.
|
||||
return c.db.ForEachNodeDirectedChannel(gossipV1, node, cb, reset)
|
||||
}
|
||||
|
||||
// FetchNodeFeatures returns the features of the given node. If no features are
|
||||
|
||||
Reference in new issue
Block a user