graph/db: thread context through ForEachChannelCacheable
What changed, and why it matters
This change threads a request-scoped cancellation context through a database method that populates the Lightning Network graph cache. It replaces a placeholder TODO context in the SQL backend with a real one, allowing long-running cache population to be cancelled if the caller stops waiting. There is no direct security bug being fixed; it is a robustness and maintainability improvement.
No immediate security action required. Treat as routine code-quality/maintenance patch. Reviewers may verify that all callers of ForEachChannelCacheable now pass a non-nil context, especially in tests, to avoid nil-context panics.
Security signals we found
Context propagation change only
Replaces context.TODO() with caller-provided context in SQL backend
No input validation, parsing, or cryptographic changes
No privilege boundary or access-control changes
No bug or vulnerability described in commit message
Evidence from the diff
The commit modifies the ForEachChannelCacheable method signature across the graph/db package to accept a context.Context parameter. The KVStore backend ignores the context (named _), while the SQLStore backend replaces context.TODO() with the supplied context. This lets populateCache pass its context down, so cache-loading can respect cancellation and deadlines. No functional change is visible in the KV backend, and the SQL backend only gains cancellation propagation.
Changed components
graph/db/graph.gograph/db/interfaces.gograph/db/kv_store.gograph/db/sql_store.goInspect captured patch +10 / −10
diff --git a/graph/db/graph.go b/graph/db/graph.go
index cb8061b..a5e79a6 100644
--- a/graph/db/graph.go
+++ b/graph/db/graph.go
@@ -185,7 +185,7 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error {
}
err = c.db.ForEachChannelCacheable(
- v, func(info *models.CachedEdgeInfo,
+ ctx, v, func(info *models.CachedEdgeInfo,
policy1,
policy2 *models.CachedEdgePolicy) error {
@@ -950,11 +950,11 @@ func (c *VersionedGraph) ForEachNodeCacheable(ctx context.Context,
}
// ForEachChannelCacheable iterates through all channel edges for the cache.
-func (c *VersionedGraph) ForEachChannelCacheable(
+func (c *VersionedGraph) ForEachChannelCacheable(ctx context.Context,
cb func(*models.CachedEdgeInfo, *models.CachedEdgePolicy,
*models.CachedEdgePolicy) error, reset func()) error {
- return c.db.ForEachChannelCacheable(c.v, cb, reset)
+ return c.db.ForEachChannelCacheable(ctx, c.v, cb, reset)
}
// DisabledChannelIDs returns the channel ids of disabled channels.
diff --git a/graph/db/interfaces.go b/graph/db/interfaces.go
index db02507..f443953 100644
--- a/graph/db/interfaces.go
+++ b/graph/db/interfaces.go
@@ -185,7 +185,7 @@ type Store interface { //nolint:interfacebloat
//
// NOTE: this method is like ForEachChannel but fetches only the data
// required for the graph cache.
- ForEachChannelCacheable(v lnwire.GossipVersion,
+ ForEachChannelCacheable(ctx context.Context, v lnwire.GossipVersion,
cb func(*models.CachedEdgeInfo, *models.CachedEdgePolicy,
*models.CachedEdgePolicy) error, reset func()) error
diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go
index ad330c8..94993c2 100644
--- a/graph/db/kv_store.go
+++ b/graph/db/kv_store.go
@@ -496,9 +496,10 @@ func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo,
//
// NOTE: this method is like ForEachChannel but fetches only the data required
// for the graph cache.
-func (c *KVStore) ForEachChannelCacheable(v lnwire.GossipVersion,
- cb func(*models.CachedEdgeInfo, *models.CachedEdgePolicy,
- *models.CachedEdgePolicy) error, reset func()) error {
+func (c *KVStore) ForEachChannelCacheable(_ context.Context,
+ v lnwire.GossipVersion, cb func(*models.CachedEdgeInfo,
+ *models.CachedEdgePolicy, *models.CachedEdgePolicy) error,
+ reset func()) error {
if v != lnwire.GossipVersion1 {
return ErrVersionNotSupportedForKVDB
diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go
index fe8ca37..745dff5 100644
--- a/graph/db/sql_store.go
+++ b/graph/db/sql_store.go
@@ -1564,12 +1564,11 @@ func (s *SQLStore) ForEachNodeCached(ctx context.Context, withAddrs bool,
//
// NOTE: this method is like ForEachChannel but fetches only the data
// required for the graph cache.
-func (s *SQLStore) ForEachChannelCacheable(v lnwire.GossipVersion,
+func (s *SQLStore) ForEachChannelCacheable(ctx context.Context,
+ v lnwire.GossipVersion,
cb func(*models.CachedEdgeInfo, *models.CachedEdgePolicy,
*models.CachedEdgePolicy) error, reset func()) error {
- ctx := context.TODO()
-
if !isKnownGossipVersion(v) {
return fmt.Errorf("unsupported gossip version: %d", v)
}
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.