Skip to content

Conversation

@ellemouton
Copy link
Collaborator

@ellemouton ellemouton commented Oct 8, 2025

A simple refactor & clean-up PR.

The main thing here is an added Version field to the models.Node struct & using a constructor to create the Node instance so that all the V1 fields are set for a V1 node. This is in preparation for dealing with V2 Nodes.

Part of #10293

@ellemouton ellemouton self-assigned this Oct 8, 2025
@gemini-code-assist
Copy link

Summary of Changes

Hello @ellemouton, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request is a refactor and cleanup aimed at preparing the codebase for supporting multiple versions of Lightning Network node announcements. It introduces a Version field to the models.Node struct, replaces direct struct instantiation with dedicated constructors for V1 nodes, and converts optional fields like Color and Alias to use fn.Option types. Additionally, it simplifies several related data structures by removing redundant cached fields and their accessor methods. The changes are applied consistently across the codebase, updating all relevant call sites and tests to align with the new design. This lays the groundwork for future extensions, such as V2 node announcements, while improving code clarity and maintainability.

Highlights

  • Node Versioning Refactor: The core change introduces a Version field to the models.Node struct and refactors node creation to use constructors (NewV1Node, NewV1ShellNode, NewShellNode). This prepares the codebase for handling multiple node announcement versions (e.g., V1, V2).
  • Optional Fields with fn.Option: The Color and Alias fields in models.Node are now wrapped in fn.Option types, making their optionality explicit. All usage sites have been updated to correctly handle these optional values using UnwrapOr or WhenSome.
  • Simplified Data Structures: The HaveNodeAnnouncement boolean field in models.Node has been replaced by a HaveAnnouncement() method. Additionally, cached ecdsa.Signature fields in ChannelAuthProof and btcec.PublicKey fields in ChannelEdgeInfo have been removed, simplifying these structs and their access patterns.
  • Codebase-Wide Adaption: Numerous files across the project, including tests, database implementations (kv_store, sql_store), RPC server logic, and routing components, have been updated to use the new node constructors and fn.Option access patterns, ensuring consistency with the refactored models.Node.
  • Graph Interface Consolidation: The graph.DB interface has been removed, and direct usage of *graphdb.ChannelGraph is now prevalent, suggesting a consolidation of graph database access mechanisms.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

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 refactor to prepare the codebase for handling multiple Node versions, specifically by adding a Version field to the models.Node struct and using a constructor to create Node instances. The changes primarily involve modifying the autopilot/prefattach_test.go, channeldb/db_test.go, discovery/chan_series.go, graph/builder.go, graph/builder_test.go, graph/db/graph.go, graph/db/graph_test.go, graph/db/interfaces.go, graph/db/kv_store.go, graph/db/models/channel_auth_proof.go, graph/db/models/channel_edge_info.go, graph/db/models/node.go, graph/db/notifications.go, graph/db/sql_migration.go, graph/db/sql_migration_test.go, lnrpc/devrpc/dev_server.go, routing/pathfind_test.go, routing/payment_session_source.go, routing/payment_session_test.go, routing/router_test.go, and server.go files. The review focuses on correctness, maintainability, and adherence to the repository's style guide, particularly concerning code documentation, commenting, spacing, and formatting.

@ellemouton ellemouton force-pushed the g175Prep2 branch 2 times, most recently from 6b66a3b to 258ca41 Compare October 14, 2025 12:35
@saubyk saubyk added this to v0.21 Oct 14, 2025
@saubyk saubyk moved this to In progress in v0.21 Oct 14, 2025
@saubyk saubyk moved this from In progress to In review in v0.21 Oct 14, 2025
Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

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

Looking great, a lot of nice clean-ups 🧹

Comment on lines +3500 to +3502
if dbNode.LastUpdate.Valid {
node.LastUpdate = time.Unix(dbNode.LastUpdate.Int64, 0)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

is there a reason why node.LastUpdate is non-optional when the db field is also nullable, whereas alias is optional for example?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we can/should defs change it later on. I think this was mainly due to Alias/Color not being used often so the diff was small. LastUpdate is used more often - so I'll do that change in a commit by itself a bit later on 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh yes, it was also cause things like alias & color do become actual optional fields but update time must always be set & isnt really optional in that sense.

but yeah, we can make this more explicit later with helpers like "ExtractV1Node" or something

}

// NewV1Node creates a new version 1 node from the passed fields.
func NewV1Node(pub route.Vertex, n *NodeV1Fields) *Node {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Using NodeV1Fields as a combined parameter somewhat defeats the purpose of making sure that a creator sets all field values, not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

what do you mean by "combined parameter"?
I think having the struct shows clearly what values need to be set? ie, with this constructor we dont expose V2-only-fields that would just be lost on persistence

Copy link
Collaborator

Choose a reason for hiding this comment

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

Imo having a struct argument makes the code slightly more readable. A long list of arguments can end up being very messy.

I think some editors/IDEs don't immediately fill struct fields (e.g. in vim it's doable but not a default) so perhaps @bitromortac was referring to that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that it's cleaner to have it the way it is, just wasn't sure because of the PR description so that all the V1 fields are set for a V1 node, because you can leave out setting some fields of the struct in principle (in contrast to having all fields as parameters to NewV1Node like @bhandras mentioned). Just wanted to generate some awareness

@lightninglabs-deploy
Copy link

@bhandras: review reminder
@ellemouton, remember to re-request review from reviewers when ready

Simplify the struct by removing un-used methods and outdated comments.
Remove the 2 sources of truth here. If we have a signature for the
node, then we have the announcement.
Add a version field to models.Node and a V1 constructor for it.
Remove various unused fields and methods.
Copy link
Collaborator

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

LGTM, very nice! 🎉

Alias: rpcNode.Alias,
// NOTE: this is a workaround to ensure that
// HaveAnnouncement() returns true so that the other
// fields are properly persisted. However,
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: comment ending seems missing.


// Color is the selected color for the node.
Color color.RGBA
Color fn.Option[color.RGBA]
Copy link
Collaborator

Choose a reason for hiding this comment

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

q: Should NodeV1Fields.Color/Alias be optional too?

}

// NewV1Node creates a new version 1 node from the passed fields.
func NewV1Node(pub route.Vertex, n *NodeV1Fields) *Node {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Imo having a struct argument makes the code slightly more readable. A long list of arguments can end up being very messy.

I think some editors/IDEs don't immediately fill struct fields (e.g. in vim it's doable but not a default) so perhaps @bitromortac was referring to that?

Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

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

LGTM ⚡

}

// NewV1Node creates a new version 1 node from the passed fields.
func NewV1Node(pub route.Vertex, n *NodeV1Fields) *Node {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that it's cleaner to have it the way it is, just wasn't sure because of the PR description so that all the V1 fields are set for a V1 node, because you can leave out setting some fields of the struct in principle (in contrast to having all fields as parameters to NewV1Node like @bhandras mentioned). Just wanted to generate some awareness

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

4 participants