What changed, and why it matters
This small code change fixes a bug where Lightning Network routing policies loaded from the database into an in-memory cache were missing a version tag. The fix explicitly marks them as version 1 policies. Without the version set, other parts of the node that rely on the version field could misinterpret the policy, potentially causing incorrect fee or time-lock calculations when routing payments through the network.
Apply the patch. Review all other code paths that construct GraphChannelPolicy from database rows to ensure Version is consistently set. Add regression tests or assertions verifying policy version after cache load. Monitor for any routing/fee anomalies on nodes running versions prior to this fix.
Security signals we found
Missing version metadata in deserialized security/routing policy
Potential for incorrect routing constraints (timelock/fees) due to default-zero version
Fix is localized and defensive, suggesting a latent correctness issue
Evidence from the diff
In graph/db/sql_store.go, the extractChannelPolicies helper now sets Version: int16(lnwire.GossipVersion1) when constructing sqlc.GraphChannelPolicy objects for both policy1 and policy2 during paginated cache loading (ListChannelsWithPoliciesForCachePaginatedRow). Previously these structs were populated from DB columns but left Version at its zero value. Downstream code that checks policy.Version may treat zero as an unknown or invalid version, which can affect graph cache behavior, policy validation, or routing decisions.
Changed components
graph/db/sql_store.goextractChannelPoliciesGraph cache reconstructionChannel routing policy handlingInspect captured patch +2 / −0
diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go
index 9a62f2f..bcb8245 100644
--- a/graph/db/sql_store.go
+++ b/graph/db/sql_store.go
@@ -4822,6 +4822,7 @@ func extractChannelPolicies(row any) (*sqlc.GraphChannelPolicy,
case sqlc.ListChannelsWithPoliciesForCachePaginatedRow:
if r.Policy1Timelock.Valid {
policy1 = &sqlc.GraphChannelPolicy{
+ Version: int16(lnwire.GossipVersion1),
Timelock: r.Policy1Timelock.Int32,
FeePpm: r.Policy1FeePpm.Int64,
BaseFeeMsat: r.Policy1BaseFeeMsat.Int64,
@@ -4838,6 +4839,7 @@ func extractChannelPolicies(row any) (*sqlc.GraphChannelPolicy,
}
if r.Policy2Timelock.Valid {
policy2 = &sqlc.GraphChannelPolicy{
+ Version: int16(lnwire.GossipVersion1),
Timelock: r.Policy2Timelock.Int32,
FeePpm: r.Policy2FeePpm.Int64,
BaseFeeMsat: r.Policy2BaseFeeMsat.Int64,
Why this scored 46/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.