diff --git a/go.mod b/go.mod index 7c501f8817..0973be6c70 100644 --- a/go.mod +++ b/go.mod @@ -213,6 +213,8 @@ replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 // allows us to specify that as an option. replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-display v1.33.0-hex-display +replace github.com/lightningnetwork/lnd/sqldb => ./sqldb + // If you change this please also update docs/INSTALL.md and GO_VERSION in // Makefile (then run `make lint` to see where else it needs to be updated as // well). diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index ee5cf8dbf1..413bfe6635 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -1593,6 +1593,8 @@ func TestGraphCacheTraversal(t *testing.T) { require.Equal(t, numChannels*2*(numNodes-1), numNodeChans) } +// fillTestGraph fills the graph with a given number of nodes and create a given +// number of channels between each node. func fillTestGraph(t testing.TB, graph *ChannelGraph, numNodes, numChannels int) (map[uint64]struct{}, []*models.Node) { @@ -3995,6 +3997,25 @@ func TestNodeIsPublic(t *testing.T) { ) } +// BenchmarkIsPublicNode measures the performance of IsPublicNode when checking +// a large number of nodes. +func BenchmarkIsPublicNode(b *testing.B) { + graph := MakeTestGraph(b) + + // Create a graph with a reasonable number of nodes and channels. + numNodes := 8000 + numChans := 4 + _, nodes := fillTestGraph(b, graph, numNodes, numChans) + + // Pick a random node to test. + nodePub := nodes[len(nodes)/2].PubKeyBytes + + for b.Loop() { + _, err := graph.IsPublicNode(nodePub) + require.NoError(b, err) + } +} + // TestDisabledChannelIDs ensures that the disabled channels within the // disabledEdgePolicyBucket are managed properly and the list returned from // DisabledChannelIDs is correct. diff --git a/sqldb/sqlc/graph.sql.go b/sqldb/sqlc/graph.sql.go index 9c27027375..a0c62fa86f 100644 --- a/sqldb/sqlc/graph.sql.go +++ b/sqldb/sqlc/graph.sql.go @@ -2653,7 +2653,7 @@ const isPublicV1Node = `-- name: IsPublicV1Node :one SELECT EXISTS ( SELECT 1 FROM graph_channels c - JOIN graph_nodes n ON n.id = c.node_id_1 OR n.id = c.node_id_2 + JOIN graph_nodes n ON n.id = c.node_id_1 -- NOTE: we hard-code the version here since the clauses -- here that determine if a node is public is specific -- to the V1 gossip protocol. In V1, a node is public @@ -2662,6 +2662,13 @@ SELECT EXISTS ( -- announcement. It is enough to just check that we have -- one of the signatures since we only ever set them -- together. + WHERE c.version = 1 + AND c.bitcoin_1_signature IS NOT NULL + AND n.pub_key = $1 + UNION ALL + SELECT 1 + FROM graph_channels c + JOIN graph_nodes n ON n.id = c.node_id_2 WHERE c.version = 1 AND c.bitcoin_1_signature IS NOT NULL AND n.pub_key = $1 diff --git a/sqldb/sqlc/queries/graph.sql b/sqldb/sqlc/queries/graph.sql index 19087fc1bd..a75c15ba77 100644 --- a/sqldb/sqlc/queries/graph.sql +++ b/sqldb/sqlc/queries/graph.sql @@ -56,7 +56,7 @@ LIMIT $3; SELECT EXISTS ( SELECT 1 FROM graph_channels c - JOIN graph_nodes n ON n.id = c.node_id_1 OR n.id = c.node_id_2 + JOIN graph_nodes n ON n.id = c.node_id_1 -- NOTE: we hard-code the version here since the clauses -- here that determine if a node is public is specific -- to the V1 gossip protocol. In V1, a node is public @@ -68,6 +68,13 @@ SELECT EXISTS ( WHERE c.version = 1 AND c.bitcoin_1_signature IS NOT NULL AND n.pub_key = $1 + UNION ALL + SELECT 1 + FROM graph_channels c + JOIN graph_nodes n ON n.id = c.node_id_2 + WHERE c.version = 1 + AND c.bitcoin_1_signature IS NOT NULL + AND n.pub_key = $1 ); -- name: DeleteUnconnectedNodes :many