Skip to content

Expose node features in GetNodeInfoResponse#231

Merged
benthecarman merged 1 commit into
lightningdevkit:mainfrom
enigbe:2026-02-expose-node-features-in-getnodeinforesponse
Jun 17, 2026
Merged

Expose node features in GetNodeInfoResponse#231
benthecarman merged 1 commit into
lightningdevkit:mainfrom
enigbe:2026-02-expose-node-features-in-getnodeinforesponse

Conversation

@enigbe

@enigbe enigbe commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What this PR does:

To run payment-activity simulations against networks of ldk-server nodes, clients such as sim-ln need to know whether a server advertises support for capabilities like keysend in its node_announcement.

This PR exposes node-announcement features through GetNodeInfoResponse.features, allowing clients to query the node directly for its advertised feature set. For now, only node-announcement features are populated; the proto documentation reflects this narrower contract while leaving room for future expansion to other feature contexts.

This is needed by the ongoing sim-ln work in bitcoin-dev-project/sim-ln#307.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 12, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @benthecarman as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@benthecarman

Copy link
Copy Markdown
Collaborator

We just get a list like this

  "features": {
    "node": [
      0,
      8,
      128,
      136,
      152,
      136,
      10,
      138,
      81,
      161
    ]
  }

would be better if this had some more info, at least giving the name of each feature so we knew what it represented

@enigbe enigbe force-pushed the 2026-02-expose-node-features-in-getnodeinforesponse branch from da2670e to 795b695 Compare June 13, 2026 09:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @benthecarman! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@benthecarman benthecarman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this format is still weird..

We have the name as the key and we put it in the name field. is_known and is_supported are both always true as the way we get them makes it inherent.

Also doesn't make it entirely clear if we are signaling the required or optional bit, just that we are signaling one of them.

We also don't need the node object here

  "features": {
    "node": {
      "DataLossProtect": {
        "name": "DataLossProtect",
        "is_supported": true,
        "is_required": true,
        "is_known": true,
        "supported_bit": 1,
        "required_bit": 0
      },

lnd does a good job of this, where the bit is the key and the data is available about it. They have is_known because you can optionally flag bits on in their config, we don't support this so we don't need this field.

    "features":  {
        "0":  {
            "name":  "data-loss-protect",
            "is_required":  true,
            "is_known":  true
        },
        "5":  {
            "name":  "upfront-shutdown-script",
            "is_required":  false,
            "is_known":  true
        },

Comment thread ldk-server/src/util/proto_adapter.rs Outdated
supported_bit,
required_bit,
});
feature.is_supported = true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

we are always setting this to true, do we even need this field?

@enigbe

enigbe commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

We have the name as the key and we put it in the name field. is_known and is_supported are both always true as the way we get them makes it inherent. Also doesn't make it entirely clear if we are signaling the required or optional bit, just that we are signaling one of them.

Fair point. I agree that it's clunky and will switch this to LND's bit-keyed style.

We also don't need the node object here

  "features": {
    "node": {
      "DataLossProtect": {
        "name": "DataLossProtect",
        "is_supported": true,
        "is_required": true,
        "is_known": true,
        "supported_bit": 1,
        "required_bit": 0
      },

lnd does a good job of this, where the bit is the key and the data is available about it. They have is_known because you can optionally flag bits on in their config, we don't support this so we don't need this field.

I added the node object to leave room for the same feature-context distinction that cln-grpc exposes through ourFeatures:

{
  "ourFeatures": {
    "init": "800898880a8a59a1",
    "node": "808898880a8a59a1",
    "channel": "",
    "invoice": "02000002024100"
  }
}

The shape I had in mind was something like this, but with decoded, instead of raw bytes:

{
  "init": {
    "0": { "name": "DataLossProtect", "is_required": true },
    "5": { "name": "UpfrontShutdownScript", "is_required": false },
    "8": { "name": "VarOnionOptin", "is_required": true }
  },
  "node": {
    "0": { "name": "DataLossProtect", "is_required": true },
    "55": { "name": "Keysend", "is_required": false }
  },
  "invoice": {
    "8": { "name": "VarOnionOptin", "is_required": true },
    "14": { "name": "PaymentSecret", "is_required": true }
  }
}

That said, since this response currently only exposes node-announcement features, I'm fine flattening it for now and adding contextual grouping later if we expose the other feature sets.

@enigbe enigbe force-pushed the 2026-02-expose-node-features-in-getnodeinforesponse branch from 795b695 to c68ae6d Compare June 16, 2026 21:32
@benthecarman

Copy link
Copy Markdown
Collaborator

Awesome looks good! Can we just sort the features by their bit, currently they are random from the hash map. Feel free to do that in a squash and we should be able to get this in!

Return the node-announcement feature set from GetNodeInfoResponse so clients
can inspect advertised node capabilities, such as keysend support, directly
from the node info API.

Decode exposed feature bytes into semantic entries keyed by the signaled BOLT
feature bit. Each entry carries the decoded name and whether that bit is
required, while presence in the map indicates the bit is signaled.
@enigbe enigbe force-pushed the 2026-02-expose-node-features-in-getnodeinforesponse branch from c68ae6d to 45c6516 Compare June 16, 2026 23:29
@enigbe

enigbe commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Awesome looks good! Can we just sort the features by their bit, currently they are random from the hash map. Feel free to do that in a squash and we should be able to get this in!

We have feature ordering by bit now by replacing the HashMap with a BtreeMap.
I also squashed the fixups.

@enigbe enigbe requested a review from benthecarman June 17, 2026 08:09

@benthecarman benthecarman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

thanks!

@benthecarman benthecarman merged commit 2b41501 into lightningdevkit:main Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants