test: check that features get removed when ...
What changed, and why it matters
This commit only adds a new test case to verify an existing behavior: when a Core Lightning plugin disables itself during startup, any feature bits it advertised should be removed from the node's public feature announcements. It does not change production code, so it cannot by itself introduce a security vulnerability or fix one.
No security action required. Review the underlying plugin feature-removal implementation separately if you want to confirm the behavior is robust, but this commit only adds regression tests.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff adds an init() handler to the test plugin tests/plugins/feature-test.py that returns {'disable': '...'} when the environment variable PLUGIN_DISABLE is set, and adds a new pytest test_plugin_feature_remove in tests/test_plugin.py that enables that environment variable, starts a node with the plugin, and asserts that bits 201 (init), 203 (node_announcement), and 205 (bolt11 invoice) are absent from getinfo()['our_features']. This is purely test coverage for previously implemented plugin-disable/feature-removal logic.
Changed components
tests/plugins/feature-test.pytests/test_plugin.pyInspect captured patch +31 / −0
diff --git a/tests/plugins/feature-test.py b/tests/plugins/feature-test.py
index 02be4500..45900216 100755
--- a/tests/plugins/feature-test.py
+++ b/tests/plugins/feature-test.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
from pyln.client import Plugin
+import os
# Register a different set feature of feature bits for each location so we can
# later check that they are being passed correctly.
@@ -12,4 +13,12 @@ plugin = Plugin(
)
+@plugin.init()
+def init(configuration, options, plugin):
+ disable = os.getenv("PLUGIN_DISABLE")
+ if disable:
+ return {'disable': 'init saying disable'}
+ return {}
+
+
plugin.run()
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index 48f4dcfe..fa9137e9 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -1748,6 +1748,28 @@ def test_plugin_feature_announce(node_factory):
assert node['features'] == expected_node_features(extra=[203])
+def test_plugin_feature_remove(node_factory, monkeypatch):
+ """Check that features registered by plugins get removed if a plugin
+ disables itself.
+
+ We set the following feature bits we don't want to include if the plugin is
+ disabled during init.
+ - 1 << 201 for `init` messages
+ - 1 << 203 for `node_announcement`
+ - 1 << 205 for bolt11 invoices
+ """
+
+ monkeypatch.setenv("PLUGIN_DISABLE", "1")
+ plugin = os.path.join(os.path.dirname(__file__), 'plugins/feature-test.py')
+ l1 = node_factory.get_node(options={'plugin': plugin})
+
+ # Check that we don't include the features set in getmanifest.
+ our_feats = l1.rpc.getinfo()["our_features"]
+ assert((int(our_feats["init"], 16) & (1 << 201)) == 0)
+ assert((int(our_feats["node"], 16) & (1 << 203)) == 0)
+ assert((int(our_feats["invoice"], 16) & (1 << 205)) == 0)
+
+
def test_hook_chaining(node_factory):
"""Check that hooks are called in order and the chain exits correctly
Why this scored 12/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.