graph/db: use V1Store interface in ChannelGraph

Use the new `V1Store` interface as a field in the `ChannelGraph` rather than
a pointer to the `KVStore` implementation in preparation for allowing a
SQL implementation of `V1Store` to be used by the `ChannelGraph`.

Note that two tests are adjusted in this commit to be skipped if the
V1Store is not the `KVStore` implementation since the tests are very
bbolt specific.
This commit is contained in:
Elle Mouton committed 2025-05-22 14:14:40 +02:00
1 parent 52018dbbec
commit 449684de87
2 files changed
+37 -39

No files matched your search

+21 -21
View File
@@ -43,7 +43,7 @@ type ChannelGraph struct {
graphCache *GraphCache
*KVStore
V1Store
*topologyManager
quit chan struct{}
@@ -65,7 +65,7 @@ func NewChannelGraph(cfg *Config, options ...ChanGraphOption) (*ChannelGraph,
}
g := &ChannelGraph{
KVStore: store,
V1Store: store,
topologyManager: newTopologyManager(),
quit: make(chan struct{}),
}
@@ -179,7 +179,7 @@ func (c *ChannelGraph) populateCache() error {
log.Info("Populating in-memory channel graph, this might take a " +
"while...")
err := c.KVStore.ForEachNodeCacheable(func(node route.Vertex,
err := c.V1Store.ForEachNodeCacheable(func(node route.Vertex,
features *lnwire.FeatureVector) error {
c.graphCache.AddNodeFeatures(node, features)
@@ -190,7 +190,7 @@ func (c *ChannelGraph) populateCache() error {
return err
}
err = c.KVStore.ForEachChannel(func(info *models.ChannelEdgeInfo,
err = c.V1Store.ForEachChannel(func(info *models.ChannelEdgeInfo,
policy1, policy2 *models.ChannelEdgePolicy) error {
c.graphCache.AddChannel(info, policy1, policy2)
@@ -224,7 +224,7 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(node route.Vertex,
return c.graphCache.ForEachChannel(node, cb)
}
return c.KVStore.ForEachNodeDirectedChannel(node, cb)
return c.V1Store.ForEachNodeDirectedChannel(node, cb)
}
// FetchNodeFeatures returns the features of the given node. If no features are
@@ -240,7 +240,7 @@ func (c *ChannelGraph) FetchNodeFeatures(node route.Vertex) (
return c.graphCache.GetFeatures(node), nil
}
return c.KVStore.FetchNodeFeatures(node)
return c.V1Store.FetchNodeFeatures(node)
}
// GraphSession will provide the call-back with access to a NodeTraverser
@@ -252,7 +252,7 @@ func (c *ChannelGraph) GraphSession(cb func(graph NodeTraverser) error) error {
return cb(c)
}
return c.KVStore.GraphSession(cb)
return c.V1Store.GraphSession(cb)
}
// ForEachNodeCached iterates through all the stored vertices/nodes in the
@@ -266,7 +266,7 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
return c.graphCache.ForEachNode(cb)
}
return c.KVStore.ForEachNodeCached(cb)
return c.V1Store.ForEachNodeCached(cb)
}
// AddLightningNode adds a vertex/node to the graph database. If the node is not
@@ -278,7 +278,7 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
func (c *ChannelGraph) AddLightningNode(node *models.LightningNode,
op ...batch.SchedulerOption) error {
err := c.KVStore.AddLightningNode(node, op...)
err := c.V1Store.AddLightningNode(node, op...)
if err != nil {
return err
}
@@ -301,7 +301,7 @@ func (c *ChannelGraph) AddLightningNode(node *models.LightningNode,
// DeleteLightningNode starts a new database transaction to remove a vertex/node
// from the database according to the node's public key.
func (c *ChannelGraph) DeleteLightningNode(nodePub route.Vertex) error {
err := c.KVStore.DeleteLightningNode(nodePub)
err := c.V1Store.DeleteLightningNode(nodePub)
if err != nil {
return err
}
@@ -322,7 +322,7 @@ func (c *ChannelGraph) DeleteLightningNode(nodePub route.Vertex) error {
func (c *ChannelGraph) AddChannelEdge(edge *models.ChannelEdgeInfo,
op ...batch.SchedulerOption) error {
err := c.KVStore.AddChannelEdge(edge, op...)
err := c.V1Store.AddChannelEdge(edge, op...)
if err != nil {
return err
}
@@ -344,7 +344,7 @@ func (c *ChannelGraph) AddChannelEdge(edge *models.ChannelEdgeInfo,
// If the cache is enabled, the edge will be added back to the graph cache if
// we still have a record of this channel in the DB.
func (c *ChannelGraph) MarkEdgeLive(chanID uint64) error {
err := c.KVStore.MarkEdgeLive(chanID)
err := c.V1Store.MarkEdgeLive(chanID)
if err != nil {
return err
}
@@ -352,7 +352,7 @@ func (c *ChannelGraph) MarkEdgeLive(chanID uint64) error {
if c.graphCache != nil {
// We need to add the channel back into our graph cache,
// otherwise we won't use it for path finding.
infos, err := c.KVStore.FetchChanInfos([]uint64{chanID})
infos, err := c.V1Store.FetchChanInfos([]uint64{chanID})
if err != nil {
return err
}
@@ -380,7 +380,7 @@ func (c *ChannelGraph) MarkEdgeLive(chanID uint64) error {
func (c *ChannelGraph) DeleteChannelEdges(strictZombiePruning, markZombie bool,
chanIDs ...uint64) error {
infos, err := c.KVStore.DeleteChannelEdges(
infos, err := c.V1Store.DeleteChannelEdges(
strictZombiePruning, markZombie, chanIDs...,
)
if err != nil {
@@ -409,7 +409,7 @@ func (c *ChannelGraph) DeleteChannelEdges(strictZombiePruning, markZombie bool,
func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) (
[]*models.ChannelEdgeInfo, error) {
edges, err := c.KVStore.DisconnectBlockAtHeight(height)
edges, err := c.V1Store.DisconnectBlockAtHeight(height)
if err != nil {
return nil, err
}
@@ -437,7 +437,7 @@ func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint,
blockHash *chainhash.Hash, blockHeight uint32) (
[]*models.ChannelEdgeInfo, error) {
edges, nodes, err := c.KVStore.PruneGraph(
edges, nodes, err := c.V1Store.PruneGraph(
spentOutputs, blockHash, blockHeight,
)
if err != nil {
@@ -482,7 +482,7 @@ func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint,
// that we only maintain a graph of reachable nodes. In the event that a pruned
// node gains more channels, it will be re-added back to the graph.
func (c *ChannelGraph) PruneGraphNodes() error {
nodes, err := c.KVStore.PruneGraphNodes()
nodes, err := c.V1Store.PruneGraphNodes()
if err != nil {
return err
}
@@ -504,7 +504,7 @@ func (c *ChannelGraph) PruneGraphNodes() error {
func (c *ChannelGraph) FilterKnownChanIDs(chansInfo []ChannelUpdateInfo,
isZombieChan func(time.Time, time.Time) bool) ([]uint64, error) {
unknown, knownZombies, err := c.KVStore.FilterKnownChanIDs(chansInfo)
unknown, knownZombies, err := c.V1Store.FilterKnownChanIDs(chansInfo)
if err != nil {
return nil, err
}
@@ -533,7 +533,7 @@ func (c *ChannelGraph) FilterKnownChanIDs(chansInfo []ChannelUpdateInfo,
// timestamps could bring it back from the dead, then we mark it
// alive, and we let it be added to the set of IDs to query our
// peer for.
err := c.KVStore.MarkEdgeLive(
err := c.V1Store.MarkEdgeLive(
info.ShortChannelID.ToUint64(),
)
// Since there is a chance that the edge could have been marked
@@ -554,7 +554,7 @@ func (c *ChannelGraph) FilterKnownChanIDs(chansInfo []ChannelUpdateInfo,
func (c *ChannelGraph) MarkEdgeZombie(chanID uint64,
pubKey1, pubKey2 [33]byte) error {
err := c.KVStore.MarkEdgeZombie(chanID, pubKey1, pubKey2)
err := c.V1Store.MarkEdgeZombie(chanID, pubKey1, pubKey2)
if err != nil {
return err
}
@@ -576,7 +576,7 @@ func (c *ChannelGraph) MarkEdgeZombie(chanID uint64,
func (c *ChannelGraph) UpdateEdgePolicy(edge *models.ChannelEdgePolicy,
op ...batch.SchedulerOption) error {
from, to, err := c.KVStore.UpdateEdgePolicy(edge, op...)
from, to, err := c.V1Store.UpdateEdgePolicy(edge, op...)
if err != nil {
return err
}
+16 -18
View File
@@ -2950,6 +2950,12 @@ func TestChannelEdgePruningUpdateIndexDeletion(t *testing.T) {
graph, err := MakeTestGraph(t)
require.NoError(t, err, "unable to make test database")
// The update index only applies to the bbolt graph.
boltStore, ok := graph.V1Store.(*KVStore)
if !ok {
t.Skipf("skipping test that is aimed at a bbolt graph DB")
}
sourceNode := createTestVertex(t)
if err := graph.SetSourceNode(sourceNode); err != nil {
t.Fatalf("unable to set source node: %v", err)
@@ -2999,7 +3005,7 @@ func TestChannelEdgePruningUpdateIndexDeletion(t *testing.T) {
timestampSet[t] = struct{}{}
}
err := kvdb.View(graph.db, func(tx kvdb.RTx) error {
err := kvdb.View(boltStore.db, func(tx kvdb.RTx) error {
edges := tx.ReadBucket(edgeBucket)
if edges == nil {
return ErrGraphNoEdgesFound
@@ -3467,6 +3473,12 @@ func TestEdgePolicyMissingMaxHtcl(t *testing.T) {
graph, err := MakeTestGraph(t)
require.NoError(t, err, "unable to make test database")
// This test currently directly edits the bytes stored in the bbolt DB.
boltStore, ok := graph.V1Store.(*KVStore)
if !ok {
t.Skipf("skipping test that is aimed at a bbolt graph DB")
}
// We'd like to test the update of edges inserted into the database, so
// we create two vertexes to connect.
node1 := createTestVertex(t)
@@ -3515,25 +3527,11 @@ func TestEdgePolicyMissingMaxHtcl(t *testing.T) {
// Attempting to deserialize these bytes should return an error.
r := bytes.NewReader(stripped)
err = kvdb.View(graph.db, func(tx kvdb.RTx) error {
nodes := tx.ReadBucket(nodeBucket)
if nodes == nil {
return ErrGraphNotFound
}
_, err = deserializeChanEdgePolicy(r)
if err != ErrEdgePolicyOptionalFieldNotFound {
t.Fatalf("expected "+
"ErrEdgePolicyOptionalFieldNotFound, got %v",
err)
}
return nil
}, func() {})
require.NoError(t, err, "error reading db")
_, err = deserializeChanEdgePolicy(r)
require.ErrorIs(t, err, ErrEdgePolicyOptionalFieldNotFound)
// Put the stripped bytes in the DB.
err = kvdb.Update(graph.db, func(tx kvdb.RwTx) error {
err = kvdb.Update(boltStore.db, func(tx kvdb.RwTx) error {
edges := tx.ReadWriteBucket(edgeBucket)
if edges == nil {
return ErrEdgeNotFound