Skip to content

Commit ac006d7

Browse files
authored
Merge pull request #10356 from Abdulkbk/ispublicnode-perf
graph: fix inefficient query for IsPublicNode
2 parents eea4840 + 68f558c commit ac006d7

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

docs/release-notes/release-notes-0.20.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@
9898
safe single-writer behavior until the wallet subsystem is fully
9999
concurrent-safe.
100100

101+
* [Modified the query for `IsPublicV1Node`](https://github.com/lightningnetwork/lnd/pull/10356)
102+
to use `UNION ALL` instead of `OR` conditions in the `WHERE` clause, improving
103+
performance when checking for public nodes especially in large graphs when using `SQL` backends.
104+
101105
## Deprecations
102106

103107
# Technical and Architectural Updates
@@ -113,5 +117,6 @@
113117

114118
# Contributors (Alphabetical Order)
115119

120+
* Abdulkbk
116121
* bitromortac
117122
* Ziggie

graph/db/graph_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,8 @@ func TestGraphCacheTraversal(t *testing.T) {
16401640
require.Equal(t, numChannels*2*(numNodes-1), numNodeChans)
16411641
}
16421642

1643+
// fillTestGraph fills the graph with a given number of nodes and create a given
1644+
// number of channels between each node.
16431645
func fillTestGraph(t testing.TB, graph *ChannelGraph, numNodes,
16441646
numChannels int) (map[uint64]struct{}, []*models.Node) {
16451647

@@ -4042,6 +4044,28 @@ func TestNodeIsPublic(t *testing.T) {
40424044
)
40434045
}
40444046

4047+
// BenchmarkIsPublicNode measures the performance of IsPublicNode when checking
4048+
// a large number of nodes.
4049+
func BenchmarkIsPublicNode(b *testing.B) {
4050+
graph := MakeTestGraph(b)
4051+
4052+
// Create a graph with a reasonable number of nodes and channels.
4053+
numNodes := 100
4054+
numChans := 4
4055+
_, nodes := fillTestGraph(b, graph, numNodes, numChans)
4056+
4057+
// Use deterministic random number generator for reproducible results.
4058+
rng := prand.New(prand.NewSource(42))
4059+
4060+
for b.Loop() {
4061+
// Query random nodes to avoid query caching and better
4062+
// represent real-world query patterns.
4063+
nodePub := nodes[rng.Intn(len(nodes))].PubKeyBytes
4064+
_, err := graph.IsPublicNode(nodePub)
4065+
require.NoError(b, err)
4066+
}
4067+
}
4068+
40454069
// TestDisabledChannelIDs ensures that the disabled channels within the
40464070
// disabledEdgePolicyBucket are managed properly and the list returned from
40474071
// DisabledChannelIDs is correct.

sqldb/sqlc/graph.sql.go

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sqldb/sqlc/queries/graph.sql

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ LIMIT $3;
7777
SELECT EXISTS (
7878
SELECT 1
7979
FROM graph_channels c
80-
JOIN graph_nodes n ON n.id = c.node_id_1 OR n.id = c.node_id_2
80+
JOIN graph_nodes n ON n.id = c.node_id_1
8181
-- NOTE: we hard-code the version here since the clauses
8282
-- here that determine if a node is public is specific
8383
-- to the V1 gossip protocol. In V1, a node is public
@@ -89,6 +89,13 @@ SELECT EXISTS (
8989
WHERE c.version = 1
9090
AND c.bitcoin_1_signature IS NOT NULL
9191
AND n.pub_key = $1
92+
UNION ALL
93+
SELECT 1
94+
FROM graph_channels c
95+
JOIN graph_nodes n ON n.id = c.node_id_2
96+
WHERE c.version = 1
97+
AND c.bitcoin_1_signature IS NOT NULL
98+
AND n.pub_key = $1
9299
);
93100

94101
-- name: DeleteUnconnectedNodes :many

0 commit comments

Comments
 (0)