From dc6259fcc35f37cfc186e10ededa1cbbf03f1a7a Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 17 Jun 2025 11:49:23 +0200 Subject: [PATCH] graph/db: thread context through to HasLightningNode --- discovery/gossiper.go | 2 +- discovery/gossiper_test.go | 4 +++- graph/builder.go | 10 +++++----- graph/builder_test.go | 7 ++++--- graph/db/graph_test.go | 6 +++--- graph/db/interfaces.go | 4 ++-- graph/db/kv_store.go | 4 ++-- graph/db/sql_store.go | 6 ++---- graph/interfaces.go | 6 ++++-- invoices/testdata/channel.db | Bin 1048576 -> 0 bytes routing/router_test.go | 8 ++++---- rpcserver.go | 2 +- 12 files changed, 31 insertions(+), 28 deletions(-) delete mode 100644 invoices/testdata/channel.db diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 3b1d24b90..2f390da5b 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -2443,7 +2443,7 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(ctx context.Context, // We'll quickly ask the router if it already has a newer update for // this node so we can skip validating signatures if not required. - if d.cfg.Graph.IsStaleNode(nodeAnn.NodeID, timestamp) { + if d.cfg.Graph.IsStaleNode(ctx, nodeAnn.NodeID, timestamp) { log.Debugf("Skipped processing stale node: %x", nodeAnn.NodeID) nMsg.err <- nil return nil, true diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index 4f8836286..fb219f41c 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -308,7 +308,9 @@ func (r *mockGraphSource) FetchLightningNode(_ context.Context, // IsStaleNode returns true if the graph source has a node announcement for the // target node with a more recent timestamp. -func (r *mockGraphSource) IsStaleNode(nodePub route.Vertex, timestamp time.Time) bool { +func (r *mockGraphSource) IsStaleNode(_ context.Context, + nodePub route.Vertex, timestamp time.Time) bool { + r.mu.Lock() defer r.mu.Unlock() diff --git a/graph/builder.go b/graph/builder.go index 0eab22033..ce8dff179 100644 --- a/graph/builder.go +++ b/graph/builder.go @@ -865,7 +865,7 @@ func (b *Builder) updateGraphWithClosedChannels( // timestamp. ErrIgnored will be returned if we already have the node, and // ErrOutdated will be returned if we have a timestamp that's after the new // timestamp. -func (b *Builder) assertNodeAnnFreshness(node route.Vertex, +func (b *Builder) assertNodeAnnFreshness(ctx context.Context, node route.Vertex, msgTimestamp time.Time) error { // If we are not already aware of this node, it means that we don't @@ -873,7 +873,7 @@ func (b *Builder) assertNodeAnnFreshness(node route.Vertex, // node announcements, we will ignore such nodes. If we do know about // this node, check that this update brings info newer than what we // already have. - lastUpdate, exists, err := b.cfg.Graph.HasLightningNode(node) + lastUpdate, exists, err := b.cfg.Graph.HasLightningNode(ctx, node) if err != nil { return errors.Errorf("unable to query for the "+ "existence of node: %v", err) @@ -996,7 +996,7 @@ func (b *Builder) addNode(ctx context.Context, node *models.LightningNode, // Before we add the node to the database, we'll check to see if the // announcement is "fresh" or not. If it isn't, then we'll return an // error. - err := b.assertNodeAnnFreshness(node.PubKeyBytes, node.LastUpdate) + err := b.assertNodeAnnFreshness(ctx, node.PubKeyBytes, node.LastUpdate) if err != nil { return err } @@ -1306,12 +1306,12 @@ func (b *Builder) AddProof(chanID lnwire.ShortChannelID, // target node with a more recent timestamp. // // NOTE: This method is part of the ChannelGraphSource interface. -func (b *Builder) IsStaleNode(node route.Vertex, +func (b *Builder) IsStaleNode(ctx context.Context, node route.Vertex, timestamp time.Time) bool { // If our attempt to assert that the node announcement is fresh fails, // then we know that this is actually a stale announcement. - err := b.assertNodeAnnFreshness(node, timestamp) + err := b.assertNodeAnnFreshness(ctx, node, timestamp) if err != nil { log.Debugf("Checking stale node %x got %v", node, err) return true diff --git a/graph/builder_test.go b/graph/builder_test.go index ca46671ca..8795fc857 100644 --- a/graph/builder_test.go +++ b/graph/builder_test.go @@ -1013,6 +1013,7 @@ func testPruneChannelGraphDoubleDisabled(t *testing.T, assumeValid bool) { // node announcements. func TestIsStaleNode(t *testing.T) { t.Parallel() + ctxb := context.Background() const startingBlockHeight = 101 ctx := createTestCtxSingleNode(t, startingBlockHeight) @@ -1053,7 +1054,7 @@ func TestIsStaleNode(t *testing.T) { // Before we add the node, if we query for staleness, we should get // false, as we haven't added the full node. updateTimeStamp := time.Unix(123, 0) - if ctx.builder.IsStaleNode(pub1, updateTimeStamp) { + if ctx.builder.IsStaleNode(ctxb, pub1, updateTimeStamp) { t.Fatalf("incorrectly detected node as stale") } @@ -1075,14 +1076,14 @@ func TestIsStaleNode(t *testing.T) { // If we use the same timestamp and query for staleness, we should get // true. - if !ctx.builder.IsStaleNode(pub1, updateTimeStamp) { + if !ctx.builder.IsStaleNode(ctxb, pub1, updateTimeStamp) { t.Fatalf("failure to detect stale node update") } // If we update the timestamp and once again query for staleness, it // should report false. newTimeStamp := time.Unix(1234, 0) - if ctx.builder.IsStaleNode(pub1, newTimeStamp) { + if ctx.builder.IsStaleNode(ctxb, pub1, newTimeStamp) { t.Fatalf("incorrectly detected node as stale") } } diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index 7e2bb653b..25409df09 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -135,7 +135,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) { dbNode, err := graph.FetchLightningNode(ctx, testPub) require.NoError(t, err, "unable to locate node") - _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes) + _, exists, err := graph.HasLightningNode(ctx, dbNode.PubKeyBytes) if err != nil { t.Fatalf("unable to query for node: %v", err) } else if !exists { @@ -288,7 +288,7 @@ func TestPartialNode(t *testing.T) { dbNode2, err := graph.FetchLightningNode(ctx, pubKey2) require.NoError(t, err) - _, exists, err := graph.HasLightningNode(dbNode1.PubKeyBytes) + _, exists, err := graph.HasLightningNode(ctx, dbNode1.PubKeyBytes) require.NoError(t, err) require.True(t, exists) @@ -302,7 +302,7 @@ func TestPartialNode(t *testing.T) { } compareNodes(t, expectedNode1, dbNode1) - _, exists, err = graph.HasLightningNode(dbNode2.PubKeyBytes) + _, exists, err = graph.HasLightningNode(ctx, dbNode2.PubKeyBytes) require.NoError(t, err) require.True(t, exists) diff --git a/graph/db/interfaces.go b/graph/db/interfaces.go index a03e0a4bf..9f5eb6c8f 100644 --- a/graph/db/interfaces.go +++ b/graph/db/interfaces.go @@ -134,8 +134,8 @@ type V1Store interface { //nolint:interfacebloat // database, a timestamp of when the data for the node was lasted // updated is returned along with a true boolean. Otherwise, an empty // time.Time is returned with a false boolean. - HasLightningNode(nodePub [33]byte) (time.Time, bool, - error) + HasLightningNode(ctx context.Context, nodePub [33]byte) (time.Time, + bool, error) // IsPublicNode is a helper method that determines whether the node with // the given public key is seen as a public node in the graph from the diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index 7212511f7..be8ab2d9d 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -3065,8 +3065,8 @@ func (c *KVStore) fetchLightningNode(tx kvdb.RTx, // timestamp of when the data for the node was lasted updated is returned along // with a true boolean. Otherwise, an empty time.Time is returned with a false // boolean. -func (c *KVStore) HasLightningNode(nodePub [33]byte) (time.Time, bool, - error) { +func (c *KVStore) HasLightningNode(_ context.Context, + nodePub [33]byte) (time.Time, bool, error) { var ( updateTime time.Time diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go index a154fccbd..1fd68a7f9 100644 --- a/graph/db/sql_store.go +++ b/graph/db/sql_store.go @@ -217,10 +217,8 @@ func (s *SQLStore) FetchLightningNode(ctx context.Context, // boolean. // // NOTE: part of the V1Store interface. -func (s *SQLStore) HasLightningNode(pubKey [33]byte) (time.Time, bool, - error) { - - ctx := context.TODO() +func (s *SQLStore) HasLightningNode(ctx context.Context, + pubKey [33]byte) (time.Time, bool, error) { var ( exists bool diff --git a/graph/interfaces.go b/graph/interfaces.go index e54795a98..e9f894041 100644 --- a/graph/interfaces.go +++ b/graph/interfaces.go @@ -46,7 +46,8 @@ type ChannelGraphSource interface { // for the target node with a more recent timestamp. This method will // also return true if we don't have an active channel announcement for // the target node. - IsStaleNode(node route.Vertex, timestamp time.Time) bool + IsStaleNode(ctx context.Context, node route.Vertex, + timestamp time.Time) bool // IsPublicNode determines whether the given vertex is seen as a public // node in the graph from the graph's source node's point of view. @@ -238,7 +239,8 @@ type DB interface { // database, a timestamp of when the data for the node was lasted // updated is returned along with a true boolean. Otherwise, an empty // time.Time is returned with a false boolean. - HasLightningNode(nodePub [33]byte) (time.Time, bool, error) + HasLightningNode(ctx context.Context, nodePub [33]byte) (time.Time, + bool, error) // FetchLightningNode attempts to look up a target node by its identity // public key. If the node isn't found in the database, then diff --git a/invoices/testdata/channel.db b/invoices/testdata/channel.db deleted file mode 100644 index 69397f529dd11a2bcab9d1fa8e64e78d18b0d29b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1048576 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