Skip to content

[v0.20.x-branch] Backport #10529: graphdb: fix backwards-compat for channel edge feature deserialization#10546

Merged
ziggie1984 merged 1 commit intov0.20.x-branchfrom
backport-10529-to-v0.20.x-branch
Feb 4, 2026
Merged

[v0.20.x-branch] Backport #10529: graphdb: fix backwards-compat for channel edge feature deserialization#10546
ziggie1984 merged 1 commit intov0.20.x-branchfrom
backport-10529-to-v0.20.x-branch

Conversation

@github-actions
Copy link

@github-actions github-actions bot commented Feb 3, 2026

Backport of #10529


This commit fixes a backwards compatibility issue that prevented nodes from upgrading from v0.19.x to v0.20.x.

In v0.19.x, channel edge features were serialized as raw feature bytes without a length prefix. In v0.20.x (commit 2f2845d), the serialization changed to use Features.Encode() which adds a 2-byte big-endian length prefix before the feature bits. The deserialization code was updated to use Features.Decode() which expects this length prefix.

When v0.20.x reads a database created by v0.19.x, Decode() tries to read a length prefix that doesn't exist, causing an EOF error:

unable to decode features: EOF

The fix adds a deserializeChanEdgeFeatures() helper that detects which format is being read and decodes accordingly:

  • New format (v0.20+): First 2 bytes encode the length of the remaining bytes. Detected when uint16(bytes[0:2]) == len(bytes)-2.
  • Legacy format (pre-v0.20): Raw feature bits without length prefix. Uses DecodeBase256 with the known length.

The format detection is safe because in the legacy format, the first byte always has at least one bit set (the serialization uses minimum bytes), so the first two bytes can never encode a value equal to len-2.

Fixes #10528.

@github-actions github-actions bot added this to the v0.20.1 milestone Feb 3, 2026
@github-actions
Copy link
Author

github-actions bot commented Feb 3, 2026

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-10529-to-v0.20.x-branch
git worktree add --checkout .worktree/backport-10529-to-v0.20.x-branch backport-10529-to-v0.20.x-branch
cd .worktree/backport-10529-to-v0.20.x-branch
git reset --hard HEAD^
git cherry-pick -x 56a7f45b998054ad290ecfe3ede57f274b58a5b4
git push --force-with-lease

This commit fixes a backwards compatibility issue that prevented nodes
from upgrading from v0.19.x to v0.20.x.

In v0.19.x, channel edge features were serialized as raw feature bytes
without a length prefix. In v0.20.x (commit 2f2845d), the serialization
changed to use Features.Encode() which adds a 2-byte big-endian length
prefix before the feature bits. The deserialization code was updated to
use Features.Decode() which expects this length prefix.

When v0.20.x reads a database created by v0.19.x, Decode() tries to read
a length prefix that doesn't exist, causing an EOF error:

    unable to decode features: EOF

The fix adds a deserializeChanEdgeFeatures() helper that detects which
format is being read and decodes accordingly:

- New format (v0.20+): First 2 bytes encode the length of the remaining
  bytes. Detected when uint16(bytes[0:2]) == len(bytes)-2.

- Legacy format (pre-v0.20): Raw feature bits without length prefix.
  Uses DecodeBase256 with the known length.

The format detection is safe because in the legacy format, the first byte
always has at least one bit set (the serialization uses minimum bytes),
so the first two bytes can never encode a value equal to len-2.

Fixes #10528.

(cherry picked from commit 56a7f45)
@Roasbeef Roasbeef force-pushed the backport-10529-to-v0.20.x-branch branch from 27202d5 to fe486e1 Compare February 4, 2026 02:24
@Roasbeef Roasbeef marked this pull request as ready for review February 4, 2026 02:24
@lightninglabs-deploy
Copy link
Collaborator

🟠 PR Severity: HIGH

Backport fix for channel edge feature deserialization | 2 files (excl. tests) | 86 lines changed

🟠 High (1 file)
  • graph/db/kv_store.go - Graph database maintenance affecting channel edge feature deserialization and backwards compatibility
🟢 Low (1 file)
  • docs/release-notes/release-notes-0.20.1.md - Release notes documentation
ℹ️ Excluded from severity calculation (1 file)
  • graph/db/kv_store_features_test.go - Test file (449 lines)

Analysis

This PR is a backport of #10529 that fixes a backwards-compatibility issue in channel edge feature deserialization. The core change is in graph/db/kv_store.go, which handles network graph maintenance - a HIGH severity component.

The fix addresses deserialization logic that could affect how channel features are read from the database. While this is a backwards-compatibility fix (generally lower risk than new features), it touches graph database code which is critical for routing and network state management.

No severity bump applied:

  • Only 2 non-test files changed
  • 86 lines changed (excluding tests)
  • Single package modified (graph/db)

This requires review by an engineer knowledgeable in the graph database and channel feature handling.


To override, add a severity-override-{critical,high,medium,low} label.

@ziggie1984 ziggie1984 added the severity-high Requires knowledgeable engineer review label Feb 4, 2026
@ziggie1984
Copy link
Collaborator

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a critical fix for a backwards compatibility issue in channel edge feature deserialization, ensuring nodes can upgrade from v0.19.x to v0.20.x without database read errors. The changes are well-implemented and demonstrate a thorough understanding of the problem.

The core of the fix is the new deserializeChanEdgeFeatures helper function, which correctly handles both legacy (raw bytes) and new (length-prefixed) feature vector formats. The use of a canonical encoding check to disambiguate potential format collisions is a robust solution.

The accompanying tests are comprehensive, covering a wide range of scenarios including empty features, legacy and new formats, and specific edge cases where format detection could be ambiguous. The inclusion of property-based tests provides strong confidence in the correctness of the fix. The release note is clear and accurately describes the change.

Overall, this is an excellent contribution that addresses a significant bug with a clean and well-tested solution. I have no further comments.

Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ziggie1984 ziggie1984 merged commit d190a01 into v0.20.x-branch Feb 4, 2026
42 checks passed
@ziggie1984 ziggie1984 deleted the backport-10529-to-v0.20.x-branch branch February 4, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog severity-high Requires knowledgeable engineer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants