From 6c76d31e894f1d457f7f478b5c1ebdc7778ad596 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 14:21:24 +0200 Subject: [PATCH] multi: let FetchLightningNode take an optional tx In preparation for the next commit which will remove the `*LightningNode` from the `ChannelEdgePolicy` struct, `FetchLightningNode` is modified to take in an optional transaction so that it can be utilised in places where a transaction exists. --- autopilot/graph.go | 2 +- channeldb/db.go | 2 +- channeldb/graph.go | 28 +++++++++++++++++++++------- channeldb/graph_test.go | 14 +++++++------- routing/pathfind_test.go | 4 ++-- routing/router.go | 2 +- routing/router_test.go | 4 ++-- rpcserver.go | 4 ++-- server.go | 2 +- 9 files changed, 38 insertions(+), 24 deletions(-) diff --git a/autopilot/graph.go b/autopilot/graph.go index 2dbcfb781..633a7b986 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -158,7 +158,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, return nil, err } - dbNode, err := d.db.FetchLightningNode(vertex) + dbNode, err := d.db.FetchLightningNode(nil, vertex) switch { case err == channeldb.ErrGraphNodeNotFound: fallthrough diff --git a/channeldb/db.go b/channeldb/db.go index bf170e2ba..d1b9f684e 100644 --- a/channeldb/db.go +++ b/channeldb/db.go @@ -1351,7 +1351,7 @@ func (d *DB) AddrsForNode(nodePub *btcec.PublicKey) ([]net.Addr, if err != nil { return nil, err } - graphNode, err := d.graph.FetchLightningNode(pubKey) + graphNode, err := d.graph.FetchLightningNode(nil, pubKey) if err != nil && err != ErrGraphNodeNotFound { return nil, err } else if err == ErrGraphNodeNotFound { diff --git a/channeldb/graph.go b/channeldb/graph.go index b97d7a746..b9d99ed8c 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -519,7 +519,7 @@ func (c *ChannelGraph) FetchNodeFeatures( } // Fallback that uses the database. - targetNode, err := c.FetchLightningNode(node) + targetNode, err := c.FetchLightningNode(nil, node) switch err { // If the node exists and has features, return them directly. case nil: @@ -2779,12 +2779,13 @@ func (c *ChannelGraph) isPublic(tx kvdb.RTx, nodePub route.Vertex, // FetchLightningNode attempts to look up a target node by its identity public // key. If the node isn't found in the database, then ErrGraphNodeNotFound is -// returned. -func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) ( +// returned. An optional transaction may be provided. If none is provided, then +// a new one will be created. +func (c *ChannelGraph) FetchLightningNode(tx kvdb.RTx, nodePub route.Vertex) ( *LightningNode, error) { var node *LightningNode - err := kvdb.View(c.db, func(tx kvdb.RTx) error { + fetch := func(tx kvdb.RTx) error { // First grab the nodes bucket which stores the mapping from // pubKey to node information. nodes := tx.ReadBucket(nodeBucket) @@ -2810,9 +2811,22 @@ func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) ( node = &n return nil - }, func() { - node = nil - }) + } + + if tx == nil { + err := kvdb.View( + c.db, fetch, func() { + node = nil + }, + ) + if err != nil { + return nil, err + } + + return node, nil + } + + err := fetch(tx) if err != nil { return nil, err } diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index fa409441b..242fed4a7 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -139,7 +139,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) { // Next, fetch the node from the database to ensure everything was // serialized properly. - dbNode, err := graph.FetchLightningNode(testPub) + dbNode, err := graph.FetchLightningNode(nil, testPub) require.NoError(t, err, "unable to locate node") if _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes); err != nil { @@ -162,7 +162,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) { // Finally, attempt to fetch the node again. This should fail as the // node should have been deleted from the database. - _, err = graph.FetchLightningNode(testPub) + _, err = graph.FetchLightningNode(nil, testPub) if err != ErrGraphNodeNotFound { t.Fatalf("fetch after delete should fail!") } @@ -190,7 +190,7 @@ func TestPartialNode(t *testing.T) { // Next, fetch the node from the database to ensure everything was // serialized properly. - dbNode, err := graph.FetchLightningNode(testPub) + dbNode, err := graph.FetchLightningNode(nil, testPub) require.NoError(t, err, "unable to locate node") if _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes); err != nil { @@ -220,7 +220,7 @@ func TestPartialNode(t *testing.T) { // Finally, attempt to fetch the node again. This should fail as the // node should have been deleted from the database. - _, err = graph.FetchLightningNode(testPub) + _, err = graph.FetchLightningNode(nil, testPub) if err != ErrGraphNodeNotFound { t.Fatalf("fetch after delete should fail!") } @@ -2560,7 +2560,7 @@ func TestPruneGraphNodes(t *testing.T) { // Finally, we'll ensure that node3, the only fully unconnected node as // properly deleted from the graph and not another node in its place. - _, err = graph.FetchLightningNode(node3.PubKeyBytes) + _, err = graph.FetchLightningNode(nil, node3.PubKeyBytes) if err == nil { t.Fatalf("node 3 should have been deleted!") } @@ -2594,13 +2594,13 @@ func TestAddChannelEdgeShellNodes(t *testing.T) { // Ensure that node1 was inserted as a full node, while node2 only has // a shell node present. - node1, err = graph.FetchLightningNode(node1.PubKeyBytes) + node1, err = graph.FetchLightningNode(nil, node1.PubKeyBytes) require.NoError(t, err, "unable to fetch node1") if !node1.HaveNodeAnnouncement { t.Fatalf("have shell announcement for node1, shouldn't") } - node2, err = graph.FetchLightningNode(node2.PubKeyBytes) + node2, err = graph.FetchLightningNode(nil, node2.PubKeyBytes) require.NoError(t, err, "unable to fetch node2") if node2.HaveNodeAnnouncement { t.Fatalf("should have shell announcement for node2, but is full") diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index c016451bd..b615d8969 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -2283,7 +2283,7 @@ func TestPathFindSpecExample(t *testing.T) { // Carol, so we set "B" as the source node so path finding starts from // Bob. bob := ctx.aliases["B"] - bobNode, err := ctx.graph.FetchLightningNode(bob) + bobNode, err := ctx.graph.FetchLightningNode(nil, bob) require.NoError(t, err, "unable to find bob") if err := ctx.graph.SetSourceNode(bobNode); err != nil { t.Fatalf("unable to set source node: %v", err) @@ -2332,7 +2332,7 @@ func TestPathFindSpecExample(t *testing.T) { // Next, we'll set A as the source node so we can assert that we create // the proper route for any queries starting with Alice. alice := ctx.aliases["A"] - aliceNode, err := ctx.graph.FetchLightningNode(alice) + aliceNode, err := ctx.graph.FetchLightningNode(nil, alice) require.NoError(t, err, "unable to find alice") if err := ctx.graph.SetSourceNode(aliceNode); err != nil { t.Fatalf("unable to set source node: %v", err) diff --git a/routing/router.go b/routing/router.go index 1eca002dd..50aa6b43e 100644 --- a/routing/router.go +++ b/routing/router.go @@ -2802,7 +2802,7 @@ func (r *ChannelRouter) GetChannelByID(chanID lnwire.ShortChannelID) ( func (r *ChannelRouter) FetchLightningNode( node route.Vertex) (*channeldb.LightningNode, error) { - return r.cfg.Graph.FetchLightningNode(node) + return r.cfg.Graph.FetchLightningNode(nil, node) } // ForEachNode is used to iterate over every node in router topology. diff --git a/routing/router_test.go b/routing/router_test.go index ea1fec287..ce05be561 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -1613,14 +1613,14 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { _, _, err = ctx.router.FindRoute(req) require.NoError(t, err, "unable to find any routes") - copy1, err := ctx.graph.FetchLightningNode(pub1) + copy1, err := ctx.graph.FetchLightningNode(nil, pub1) require.NoError(t, err, "unable to fetch node") if copy1.Alias != n1.Alias { t.Fatalf("fetched node not equal to original") } - copy2, err := ctx.graph.FetchLightningNode(pub2) + copy2, err := ctx.graph.FetchLightningNode(nil, pub2) require.NoError(t, err, "unable to fetch node") if copy2.Alias != n2.Alias { diff --git a/rpcserver.go b/rpcserver.go index 67337e08d..a9bd480cf 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -6135,7 +6135,7 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, // With the public key decoded, attempt to fetch the node corresponding // to this public key. If the node cannot be found, then an error will // be returned. - node, err := graph.FetchLightningNode(pubKey) + node, err := graph.FetchLightningNode(nil, pubKey) switch { case err == channeldb.ErrGraphNodeNotFound: return nil, status.Error(codes.NotFound, err.Error()) @@ -7107,7 +7107,7 @@ func (r *rpcServer) ForwardingHistory(ctx context.Context, return "", err } - peer, err := r.server.graphDB.FetchLightningNode(vertex) + peer, err := r.server.graphDB.FetchLightningNode(nil, vertex) if err != nil { return "", err } diff --git a/server.go b/server.go index 85cb7616a..e9da0dc35 100644 --- a/server.go +++ b/server.go @@ -4596,7 +4596,7 @@ func (s *server) fetchNodeAdvertisedAddrs(pub *btcec.PublicKey) ([]net.Addr, err return nil, err } - node, err := s.graphDB.FetchLightningNode(vertex) + node, err := s.graphDB.FetchLightningNode(nil, vertex) if err != nil { return nil, err }