graph/db: convert other node CRUD methods

Convert a few more CRUD methods to handle v2 nodes. Then update some
more tests to be run against both v1 and v2 nodes.
This commit is contained in:
Elle Mouton committed 2026-02-13 07:21:21 +02:00
1 parent 7a5a588176
commit 7bb38651d9
7 files changed
+82 -63

No files matched your search

+14 -12
View File
@@ -618,13 +618,6 @@ func (c *ChannelGraph) ForEachNodeCacheable(ctx context.Context,
return c.db.ForEachNodeCacheable(ctx, cb, reset)
}
// LookupAlias attempts to return the alias as advertised by the target node.
func (c *ChannelGraph) LookupAlias(ctx context.Context,
pub *btcec.PublicKey) (string, error) {
return c.db.LookupAlias(ctx, lnwire.GossipVersion1, pub)
}
// NodeUpdatesInHorizon returns all known lightning nodes with updates in the
// range.
func (c *ChannelGraph) NodeUpdatesInHorizon(startTime, endTime time.Time,
@@ -755,11 +748,6 @@ func (c *ChannelGraph) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
return c.db.IsClosedScid(scid)
}
// SourceNode returns the source node of the graph.
func (c *ChannelGraph) SourceNode(ctx context.Context) (*models.Node, error) {
return c.db.SourceNode(ctx, lnwire.GossipVersion1)
}
// SetSourceNode sets the source node within the graph database.
func (c *ChannelGraph) SetSourceNode(ctx context.Context,
node *models.Node) error {
@@ -828,6 +816,20 @@ func (c *VersionedGraph) HasNode(ctx context.Context, nodePub [33]byte) (bool,
return c.db.HasNode(ctx, c.v, nodePub)
}
// LookupAlias attempts to return the alias as advertised by the target node.
func (c *VersionedGraph) LookupAlias(ctx context.Context,
pub *btcec.PublicKey) (string, error) {
return c.db.LookupAlias(ctx, c.v, pub)
}
// SourceNode returns the source node of the graph.
func (c *VersionedGraph) SourceNode(ctx context.Context) (*models.Node,
error) {
return c.db.SourceNode(ctx, c.v)
}
// MakeTestGraph creates a new instance of the ChannelGraph for testing
// purposes. The backing Store implementation depends on the version of
// NewTestDB included in the current build.
+17 -10
View File
@@ -130,6 +130,14 @@ var versionedTests = []versionedTest{
name: "node crud",
test: testNodeInsertionAndDeletion,
},
{
name: "source node",
test: testSourceNode,
},
{
name: "alias lookup",
test: testAliasLookup,
},
}
// TestVersionedDBs runs various tests against both v1 and v2 versioned
@@ -414,16 +422,15 @@ func TestPartialNode(t *testing.T) {
require.ErrorIs(t, err, ErrGraphNodeNotFound)
}
// TestAliasLookup tests the alias lookup functionality of the graph store.
func TestAliasLookup(t *testing.T) {
t.Parallel()
// testAliasLookup tests the alias lookup functionality of the graph store.
func testAliasLookup(t *testing.T, v lnwire.GossipVersion) {
ctx := t.Context()
graph := MakeTestGraph(t)
graph := NewVersionedGraph(MakeTestGraph(t), v)
// We'd like to test the alias index within the database, so first
// create a new test node.
testNode := createTestVertex(t, lnwire.GossipVersion1)
testNode := createTestVertex(t, v)
// Add the node to the graph's database, this should also insert an
// entry into the alias index for this node.
@@ -438,23 +445,23 @@ func TestAliasLookup(t *testing.T) {
require.Equal(t, testNode.Alias.UnwrapOr(""), dbAlias)
// Ensure that looking up a non-existent alias results in an error.
node := createTestVertex(t, lnwire.GossipVersion1)
node := createTestVertex(t, v)
nodePub, err = node.PubKey()
require.NoError(t, err, "unable to generate pubkey")
_, err = graph.LookupAlias(ctx, nodePub)
require.ErrorIs(t, err, ErrNodeAliasNotFound)
}
// TestSourceNode tests the source node functionality of the graph store.
func TestSourceNode(t *testing.T) {
// testSourceNode tests the source node functionality of the graph store.
func testSourceNode(t *testing.T, v lnwire.GossipVersion) {
t.Parallel()
ctx := t.Context()
graph := MakeTestGraph(t)
graph := NewVersionedGraph(MakeTestGraph(t), v)
// We'd like to test the setting/getting of the source node, so we
// first create a fake node to use within the test.
testNode := createTestVertex(t, lnwire.GossipVersion1)
testNode := createTestVertex(t, v)
// Attempt to fetch the source node, this should return an error as the
// source node hasn't yet been set.
+1 -1
View File
@@ -524,7 +524,7 @@ func (s *SQLStore) SourceNode(ctx context.Context,
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
_, nodePub, err := s.getSourceNode(ctx, db, v)
if err != nil {
return fmt.Errorf("unable to fetch V1 source node: %w",
return fmt.Errorf("unable to fetch source node: %w",
err)
}
+41 -31
View File
@@ -417,7 +417,10 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
}
return &testGraphInstance{
graph: graph,
graph: graph,
v1Graph: graphdb.NewVersionedGraph(
graph, lnwire.GossipVersion1,
),
mcBackend: mcBackend,
aliasMap: aliasMap,
privKeyMap: privKeyMap,
@@ -487,6 +490,7 @@ type testChannel struct {
type testGraphInstance struct {
graph *graphdb.ChannelGraph
v1Graph *graphdb.VersionedGraph
mcBackend kvdb.Backend
// aliasMap is a map from a node's alias to its public key. This type is
@@ -781,7 +785,10 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
}
return &testGraphInstance{
graph: graph,
graph: graph,
v1Graph: graphdb.NewVersionedGraph(
graph, lnwire.GossipVersion1,
),
mcBackend: graphBackend,
aliasMap: aliasMap,
privKeyMap: privKeyMap,
@@ -1095,7 +1102,7 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
expectedHops := test.expectedHops
expectedHopCount := len(expectedHops)
sourceNode, err := graphInstance.graph.SourceNode(ctx)
sourceNode, err := graphInstance.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
sourceVertex := route.Vertex(sourceNode.PubKeyBytes)
@@ -1107,7 +1114,7 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
paymentAmt := lnwire.NewMSatFromSatoshis(test.paymentAmt)
target := graphInstance.aliasMap[test.target]
path, err := dbFindPath(
graphInstance.graph, nil, &mockBandwidthHints{},
graphInstance.v1Graph, nil, &mockBandwidthHints{},
&RestrictParams{
FeeLimit: test.feeLimit,
ProbabilitySource: noProbabilitySource,
@@ -1237,7 +1244,7 @@ func runPathFindingWithAdditionalEdges(t *testing.T, useCache bool) {
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
paymentAmt := lnwire.NewMSatFromSatoshis(100)
@@ -1282,7 +1289,8 @@ func runPathFindingWithAdditionalEdges(t *testing.T, useCache bool) {
[]*unifiedEdge, error) {
return dbFindPath(
graph.graph, additionalEdges, &mockBandwidthHints{},
graph.v1Graph, additionalEdges,
&mockBandwidthHints{},
r, testPathFindingConfig,
sourceNode.PubKeyBytes, doge.PubKeyBytes, paymentAmt,
0, 0,
@@ -1322,7 +1330,7 @@ func runPathFindingWithBlindedPathDuplicateHop(t *testing.T, useCache bool) {
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
paymentAmt := lnwire.NewMSatFromSatoshis(100)
@@ -1396,7 +1404,7 @@ func runPathFindingWithBlindedPathDuplicateHop(t *testing.T, useCache bool) {
[]*unifiedEdge, error) {
return dbFindPath(
graph.graph, blindedPath, &mockBandwidthHints{},
graph.v1Graph, blindedPath, &mockBandwidthHints{},
r, testPathFindingConfig,
sourceNode.PubKeyBytes, dummyTarget, paymentAmt,
0, 0,
@@ -1456,7 +1464,7 @@ func runPathFindingWithRedundantAdditionalEdges(t *testing.T, useCache bool) {
}
path, err := dbFindPath(
ctx.graph, additionalEdges, ctx.bandwidthHints,
ctx.v1Graph, additionalEdges, ctx.bandwidthHints,
&ctx.restrictParams, &ctx.pathFindingConfig, ctx.source, target,
paymentAmt, ctx.timePref, 0,
)
@@ -1809,7 +1817,7 @@ func runPathNotAvailable(t *testing.T, useCache bool) {
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
// With the test graph loaded, we'll test that queries for target that
@@ -1822,7 +1830,7 @@ func runPathNotAvailable(t *testing.T, useCache bool) {
copy(unknownNode[:], unknownNodeBytes)
_, err = dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, unknownNode, 100, 0, 0,
)
@@ -1865,14 +1873,14 @@ func runDestTLVGraphFallback(t *testing.T, useCache bool) {
ctx := newPathFindingTestContext(t, useCache, testChannels, "roasbeef")
sourceNode, err := ctx.graph.SourceNode(t.Context())
sourceNode, err := ctx.v1Graph.SourceNode(t.Context())
require.NoError(t, err, "unable to fetch source node")
find := func(r *RestrictParams,
target route.Vertex) ([]*unifiedEdge, error) {
return dbFindPath(
ctx.graph, nil, &mockBandwidthHints{},
ctx.v1Graph, nil, &mockBandwidthHints{},
r, testPathFindingConfig,
sourceNode.PubKeyBytes, target, 100, 0, 0,
)
@@ -2084,7 +2092,7 @@ func runPathInsufficientCapacity(t *testing.T, useCache bool) {
require.NoError(t, err, "unable to create graph")
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
// Next, test that attempting to find a path in which the current
@@ -2099,7 +2107,7 @@ func runPathInsufficientCapacity(t *testing.T, useCache bool) {
payAmt := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin)
_, err = dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2115,7 +2123,7 @@ func runRouteFailMinHTLC(t *testing.T, useCache bool) {
require.NoError(t, err, "unable to create graph")
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
// We'll not attempt to route an HTLC of 10 SAT from roasbeef to Son
@@ -2124,7 +2132,7 @@ func runRouteFailMinHTLC(t *testing.T, useCache bool) {
target := graph.aliasMap["songoku"]
payAmt := lnwire.MilliSatoshi(10)
_, err = dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2200,7 +2208,7 @@ func runRouteFailDisabledEdge(t *testing.T, useCache bool) {
require.NoError(t, err, "unable to create graph")
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
// First, we'll try to route from roasbeef -> sophon. This should
@@ -2208,7 +2216,7 @@ func runRouteFailDisabledEdge(t *testing.T, useCache bool) {
target := graph.aliasMap["sophon"]
payAmt := lnwire.NewMSatFromSatoshis(105000)
_, err = dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2232,7 +2240,7 @@ func runRouteFailDisabledEdge(t *testing.T, useCache bool) {
}
_, err = dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2252,7 +2260,7 @@ func runRouteFailDisabledEdge(t *testing.T, useCache bool) {
// If we attempt to route through that edge, we should get a failure as
// it is no longer eligible.
_, err = dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2269,7 +2277,7 @@ func runPathSourceEdgesBandwidth(t *testing.T, useCache bool) {
require.NoError(t, err, "unable to create graph")
ctx := t.Context()
sourceNode, err := graph.graph.SourceNode(ctx)
sourceNode, err := graph.v1Graph.SourceNode(ctx)
require.NoError(t, err, "unable to fetch source node")
// First, we'll try to route from roasbeef -> sophon. This should
@@ -2278,7 +2286,7 @@ func runPathSourceEdgesBandwidth(t *testing.T, useCache bool) {
target := graph.aliasMap["sophon"]
payAmt := lnwire.NewMSatFromSatoshis(50000)
path, err := dbFindPath(
graph.graph, nil, &mockBandwidthHints{},
graph.v1Graph, nil, &mockBandwidthHints{},
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2299,7 +2307,7 @@ func runPathSourceEdgesBandwidth(t *testing.T, useCache bool) {
// Since both these edges has a bandwidth of zero, no path should be
// found.
_, err = dbFindPath(
graph.graph, nil, bandwidths,
graph.v1Graph, nil, bandwidths,
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2314,7 +2322,7 @@ func runPathSourceEdgesBandwidth(t *testing.T, useCache bool) {
// Now, if we attempt to route again, we should find the path via
// phamnuven, as the other source edge won't be considered.
path, err = dbFindPath(
graph.graph, nil, bandwidths,
graph.v1Graph, nil, bandwidths,
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -2340,7 +2348,7 @@ func runPathSourceEdgesBandwidth(t *testing.T, useCache bool) {
// Since we ignore disable flags for local channels, a path should
// still be found.
path, err = dbFindPath(
graph.graph, nil, bandwidths,
graph.v1Graph, nil, bandwidths,
noRestrictions, testPathFindingConfig,
sourceNode.PubKeyBytes, target, payAmt, 0, 0,
)
@@ -3184,6 +3192,7 @@ func runInboundFees(t *testing.T, useCache bool) {
type pathFindingTestContext struct {
t *testing.T
graph *graphdb.ChannelGraph
v1Graph *graphdb.VersionedGraph
restrictParams RestrictParams
bandwidthHints bandwidthHints
pathFindingConfig PathFindingConfig
@@ -3201,7 +3210,7 @@ func newPathFindingTestContext(t *testing.T, useCache bool,
)
require.NoError(t, err, "unable to create graph")
sourceNode, err := testGraphInstance.graph.SourceNode(
sourceNode, err := testGraphInstance.v1Graph.SourceNode(
t.Context(),
)
require.NoError(t, err, "unable to fetch source node")
@@ -3212,6 +3221,7 @@ func newPathFindingTestContext(t *testing.T, useCache bool,
source: route.Vertex(sourceNode.PubKeyBytes),
pathFindingConfig: *testPathFindingConfig,
graph: testGraphInstance.graph,
v1Graph: testGraphInstance.v1Graph,
restrictParams: *noRestrictions,
bandwidthHints: &mockBandwidthHints{},
}
@@ -3247,7 +3257,7 @@ func (c *pathFindingTestContext) findPath(target route.Vertex,
error) {
return dbFindPath(
c.graph, nil, c.bandwidthHints, &c.restrictParams,
c.v1Graph, nil, c.bandwidthHints, &c.restrictParams,
&c.pathFindingConfig, c.source, target, amt, c.timePref, 0,
)
}
@@ -3255,7 +3265,7 @@ func (c *pathFindingTestContext) findPath(target route.Vertex,
func (c *pathFindingTestContext) findBlindedPaths(
restrictions *blindedPathRestrictions) ([][]blindedHop, error) {
return dbFindBlindedPaths(c.graph, restrictions)
return dbFindBlindedPaths(c.v1Graph, restrictions)
}
func (c *pathFindingTestContext) assertPath(path []*unifiedEdge,
@@ -3277,7 +3287,7 @@ func (c *pathFindingTestContext) assertPath(path []*unifiedEdge,
// dbFindPath calls findPath after getting a db transaction from the database
// graph.
func dbFindPath(graph *graphdb.ChannelGraph,
func dbFindPath(graph *graphdb.VersionedGraph,
additionalEdges map[route.Vertex][]AdditionalEdge,
bandwidthHints bandwidthHints,
r *RestrictParams, cfg *PathFindingConfig,
@@ -3315,7 +3325,7 @@ func dbFindPath(graph *graphdb.ChannelGraph,
// dbFindBlindedPaths calls findBlindedPaths after getting a db transaction from
// the database graph.
func dbFindBlindedPaths(graph *graphdb.ChannelGraph,
func dbFindBlindedPaths(graph *graphdb.VersionedGraph,
restrictions *blindedPathRestrictions) ([][]blindedHop, error) {
sourceNode, err := graph.SourceNode(context.Background())
+3 -3
View File
@@ -132,7 +132,7 @@ func createTestCtxFromGraphInstanceAssumeValid(t *testing.T,
)
require.NoError(t, err)
sourceNode, err := graphInstance.graph.SourceNode(t.Context())
sourceNode, err := graphInstance.v1Graph.SourceNode(t.Context())
require.NoError(t, err)
sessionSource := &SessionSource{
GraphSessionFactory: graphInstance.graph,
@@ -1205,7 +1205,7 @@ func TestFindPathFeeWeighting(t *testing.T) {
var preImage [32]byte
copy(preImage[:], bytes.Repeat([]byte{9}, 32))
sourceNode, err := ctx.graph.SourceNode(t.Context())
sourceNode, err := ctx.v1Graph.SourceNode(t.Context())
require.NoError(t, err, "unable to fetch source node")
amt := lnwire.MilliSatoshi(100)
@@ -1216,7 +1216,7 @@ func TestFindPathFeeWeighting(t *testing.T) {
// the edge weighting, we should select the direct path over the 2 hop
// path even though the direct path has a higher potential time lock.
path, err := dbFindPath(
ctx.graph, nil, &mockBandwidthHints{},
ctx.v1Graph, nil, &mockBandwidthHints{},
noRestrictions,
testPathFindingConfig,
sourceNode.PubKeyBytes, target, amt, 0, 0,
+3 -3
View File
@@ -704,7 +704,7 @@ func (r *rpcServer) addDeps(ctx context.Context, s *server,
invoiceHtlcModifier *invoices.HtlcModificationInterceptor) error {
// Set up router rpc backend.
selfNode, err := s.graphDB.SourceNode(ctx)
selfNode, err := s.v1Graph.SourceNode(ctx)
if err != nil {
return err
}
@@ -4995,7 +4995,7 @@ func createRPCOpenChannel(ctx context.Context, r *rpcServer,
// Look up our channel peer's node alias if the caller requests it.
if peerAliasLookup {
peerAlias, err := r.server.graphDB.LookupAlias(ctx, nodePub)
peerAlias, err := r.server.v1Graph.LookupAlias(ctx, nodePub)
if err != nil {
peerAlias = fmt.Sprintf("unable to lookup "+
"peer alias: %v", err)
@@ -7909,7 +7909,7 @@ const feeBase float64 = 1000000
func (r *rpcServer) FeeReport(ctx context.Context,
_ *lnrpc.FeeReportRequest) (*lnrpc.FeeReportResponse, error) {
channelGraph := r.server.graphDB
channelGraph := r.server.v1Graph
selfNode, err := channelGraph.SourceNode(ctx)
if err != nil {
return nil, err
+3 -3
View File
@@ -988,7 +988,7 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
MinProbability: routingConfig.MinRouteProbability,
}
sourceNode, err := dbs.GraphDB.SourceNode(ctx)
sourceNode, err := s.v1Graph.SourceNode(ctx)
if err != nil {
return nil, fmt.Errorf("error getting source node: %w", err)
}
@@ -3440,7 +3440,7 @@ func (s *server) updateAndBroadcastSelfNode(ctx context.Context,
// Update the on-disk version of our announcement.
// Load and modify self node istead of creating anew instance so we
// don't risk overwriting any existing values.
selfNode, err := s.graphDB.SourceNode(ctx)
selfNode, err := s.v1Graph.SourceNode(ctx)
if err != nil {
return fmt.Errorf("unable to get current source node: %w", err)
}
@@ -5624,7 +5624,7 @@ func (s *server) setSelfNode(ctx context.Context, nodePub route.Vertex,
nodeLastUpdate = time.Now()
)
srcNode, err := s.graphDB.SourceNode(ctx)
srcNode, err := s.v1Graph.SourceNode(ctx)
switch {
case err == nil:
// If we have a source node persisted in the DB already, then we