Skip to content

Integrating VLS option on tests #8917

Open
enaples wants to merge 5 commits intoElementsProject:masterfrom
enaples:vls-hsmd-test
Open

Integrating VLS option on tests #8917
enaples wants to merge 5 commits intoElementsProject:masterfrom
enaples:vls-hsmd-test

Conversation

@enaples
Copy link
Copy Markdown
Collaborator

@enaples enaples commented Feb 26, 2026

Important

26.04 FREEZE March 11th: Non-bugfix PRs not ready by this date will wait for 26.06.

RC1 is scheduled on March 23rd

The final release is scheduled for April 15th.

Checklist

Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes.
  • Documentation has been reviewed and updated as needed.
  • Related issues have been listed and linked, including any that this PR closes.
  • Important All PRs must consider how to reverse any persistent changes for tools/lightning-downgrade

Changelog-None

Refactoring fixtures to test VLS implementation

The goal is to integrate VLS testing into the CLN test suite in a way that is self-contained — no changes to the pyln-testing library — and flexible enough to test different VLS implementations at different stages (different repos or commits) against the current CLN version, taking inspiration from tools/reckless.

The core idea is that ValidatingLightningSignerD should be generic: driven by the repos variable and optionally a target commit, it clones, builds and manages any conforming signer implementation. The fixture layer then decides which nodes use it and which implementation to test (so far only this is supported).

@enaples
Copy link
Copy Markdown
Collaborator Author

enaples commented Feb 26, 2026

On tests/test_pay.py, the test_simple_vls

@pytest.mark.openchannel('v1')
@pytest.mark.openchannel('v2')
def test_vls_simple(node_factory):
    l1, l2 = node_factory.line_graph(2, opts={'use_vls': True})

    inv = l2.rpc.invoice(123000, 'test_vls_simple', 'description')['bolt11']
    details = l1.dev_pay(inv, dev_use_shadow=False)
    assert details['status'] == 'complete'
    assert details['amount_msat'] == Millisatoshi(123000)
    assert details['destination'] == l2.info['id']

because some error on vls-side. I report logs for convenience:

lightningd-2 2026-02-26T11:29:47.518Z INFO    lightningd: v25.12-389-gb62be79-modded
lightningd-2 2026-02-26T11:29:47.664Z DEBUG   lightningd: Opened log file -
lightningd-2 2026-02-26T11:29:47.664Z DEBUG   lightningd: Opened log file /tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/log
lightningd-2 2026-02-26T11:29:47.666Z DEBUG   plugin-manager: started(81552) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/autoclean
lightningd-1 2026-02-26T11:29:47.518Z INFO    lightningd: v25.12-389-gb62be79-modded
lightningd-1 2026-02-26T11:29:47.666Z DEBUG   lightningd: Opened log file -
lightningd-1 2026-02-26T11:29:47.666Z DEBUG   lightningd: Opened log file /tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/log
lightningd-2 2026-02-26T11:29:47.667Z DEBUG   plugin-manager: started(81553) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/chanbackup
lightningd-1 2026-02-26T11:29:47.667Z DEBUG   plugin-manager: started(81554) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/autoclean
lightningd-2 2026-02-26T11:29:47.668Z DEBUG   plugin-manager: started(81555) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/bcli
lightningd-1 2026-02-26T11:29:47.668Z DEBUG   plugin-manager: started(81556) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/chanbackup
lightningd-2 2026-02-26T11:29:47.668Z DEBUG   plugin-manager: started(81557) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/commando
lightningd-1 2026-02-26T11:29:47.669Z DEBUG   plugin-manager: started(81558) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/bcli
lightningd-2 2026-02-26T11:29:47.669Z DEBUG   plugin-manager: started(81559) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/funder
lightningd-1 2026-02-26T11:29:47.670Z DEBUG   plugin-manager: started(81560) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/commando
lightningd-2 2026-02-26T11:29:47.670Z DEBUG   plugin-manager: started(81561) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/topology
lightningd-1 2026-02-26T11:29:47.672Z DEBUG   plugin-manager: started(81562) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/funder
lightningd-2 2026-02-26T11:29:47.674Z DEBUG   plugin-manager: started(81563) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/exposesecret
lightningd-1 2026-02-26T11:29:47.674Z DEBUG   plugin-manager: started(81564) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/topology
lightningd-1 2026-02-26T11:29:47.675Z DEBUG   plugin-manager: started(81565) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/exposesecret
lightningd-2 2026-02-26T11:29:47.675Z DEBUG   plugin-manager: started(81566) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/keysend
lightningd-2 2026-02-26T11:29:47.676Z DEBUG   plugin-manager: started(81567) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/offers
lightningd-1 2026-02-26T11:29:47.676Z DEBUG   plugin-manager: started(81568) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/keysend
lightningd-1 2026-02-26T11:29:47.677Z DEBUG   plugin-manager: started(81570) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/offers
lightningd-2 2026-02-26T11:29:47.678Z DEBUG   plugin-manager: started(81569) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/pay
lightningd-1 2026-02-26T11:29:47.678Z DEBUG   plugin-manager: started(81571) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/pay
lightningd-1 2026-02-26T11:29:47.681Z DEBUG   plugin-manager: started(81573) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/recklessrpc
lightningd-2 2026-02-26T11:29:47.681Z DEBUG   plugin-manager: started(81572) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/recklessrpc
lightningd-1 2026-02-26T11:29:47.682Z DEBUG   plugin-manager: started(81574) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/recover
lightningd-2 2026-02-26T11:29:47.682Z DEBUG   plugin-manager: started(81575) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/recover
lightningd-2 2026-02-26T11:29:47.683Z DEBUG   plugin-manager: started(81577) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/txprepare
lightningd-1 2026-02-26T11:29:47.684Z DEBUG   plugin-manager: started(81576) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/txprepare
lightningd-2 2026-02-26T11:29:47.684Z DEBUG   plugin-manager: started(81578) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-renepay
lightningd-1 2026-02-26T11:29:47.685Z DEBUG   plugin-manager: started(81579) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-renepay
lightningd-2 2026-02-26T11:29:47.687Z DEBUG   plugin-manager: started(81580) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-xpay
lightningd-1 2026-02-26T11:29:47.687Z DEBUG   plugin-manager: started(81581) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-xpay
lightningd-2 2026-02-26T11:29:47.688Z DEBUG   plugin-manager: started(81582) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/spenderp
lightningd-1 2026-02-26T11:29:47.689Z DEBUG   plugin-manager: started(81583) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/spenderp
lightningd-2 2026-02-26T11:29:47.689Z DEBUG   plugin-manager: started(81584) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-askrene
lightningd-1 2026-02-26T11:29:47.690Z DEBUG   plugin-manager: started(81585) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-askrene
lightningd-1 2026-02-26T11:29:47.691Z DEBUG   plugin-manager: started(81587) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/sql
lightningd-2 2026-02-26T11:29:47.692Z DEBUG   plugin-manager: started(81586) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/sql
lightningd-2 2026-02-26T11:29:47.693Z DEBUG   plugin-manager: started(81589) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-grpc
lightningd-1 2026-02-26T11:29:47.693Z DEBUG   plugin-manager: started(81588) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-grpc
lightningd-1 2026-02-26T11:29:47.694Z DEBUG   plugin-manager: started(81591) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/clnrest
lightningd-2 2026-02-26T11:29:47.695Z DEBUG   plugin-manager: started(81590) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/clnrest
lightningd-1 2026-02-26T11:29:47.695Z DEBUG   plugin-manager: started(81592) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-lsps-client
lightningd-2 2026-02-26T11:29:47.697Z DEBUG   plugin-manager: started(81593) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-lsps-client
lightningd-1 2026-02-26T11:29:47.697Z DEBUG   plugin-manager: started(81594) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-lsps-service
lightningd-2 2026-02-26T11:29:47.699Z DEBUG   plugin-manager: started(81595) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-lsps-service
lightningd-1 2026-02-26T11:29:47.699Z DEBUG   plugin-manager: started(81596) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/wss-proxy
lightningd-2 2026-02-26T11:29:47.700Z DEBUG   plugin-manager: started(81597) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/wss-proxy
lightningd-1 2026-02-26T11:29:47.701Z DEBUG   plugin-manager: started(81598) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-bip353
lightningd-2 2026-02-26T11:29:47.703Z DEBUG   plugin-manager: started(81599) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/cln-bip353
lightningd-1 2026-02-26T11:29:47.706Z DEBUG   plugin-manager: started(81600) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/bookkeeper
lightningd-2 2026-02-26T11:29:47.706Z DEBUG   plugin-manager: started(81601) /Users/emanuele/cln-versions/vls-hsmd-test/plugins/bookkeeper
lightningd-2 2026-02-26T11:29:47.712Z TRACE   plugin-cln-lsps-client: Plugin logging initialized
lightningd-2 2026-02-26T11:29:47.713Z TRACE   plugin-cln-lsps-service: Plugin logging initialized
lightningd-1 2026-02-26T11:29:47.714Z TRACE   plugin-cln-lsps-client: Plugin logging initialized
lightningd-1 2026-02-26T11:29:47.714Z TRACE   plugin-cln-lsps-service: Plugin logging initialized
lightningd-1 2026-02-26T11:29:47.717Z UNUSUAL plugin-bookkeeper: topic 'utxo_deposit' is not a known notification topic
lightningd-1 2026-02-26T11:29:47.717Z UNUSUAL plugin-bookkeeper: topic 'utxo_spend' is not a known notification topic
lightningd-1 2026-02-26T11:29:47.717Z DEBUG   lightningd: io_break: check_plugins_manifests
lightningd-2 2026-02-26T11:29:47.717Z UNUSUAL plugin-bookkeeper: topic 'utxo_deposit' is not a known notification topic
lightningd-2 2026-02-26T11:29:47.717Z UNUSUAL plugin-bookkeeper: topic 'utxo_spend' is not a known notification topic
lightningd-2 2026-02-26T11:29:47.717Z DEBUG   lightningd: io_break: check_plugins_manifests
lightningd-2 2026-02-26T11:29:47.718Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_channeld
lightningd-1 2026-02-26T11:29:47.718Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_channeld
lightningd-1 2026-02-26T11:29:47.732Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_closingd
lightningd-2 2026-02-26T11:29:47.732Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_closingd
lightningd-1 2026-02-26T11:29:47.738Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_connectd
lightningd-2 2026-02-26T11:29:47.738Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_connectd
lightningd-1 2026-02-26T11:29:47.745Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_gossipd
lightningd-2 2026-02-26T11:29:47.745Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_gossipd
lightningd-2 2026-02-26T11:29:47.752Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_gossip_compactd
lightningd-1 2026-02-26T11:29:47.752Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_gossip_compactd
lightningd-1 2026-02-26T11:29:47.758Z DEBUG   lightningd: testing /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/validating-lightning-signer/target/debug/remote_hsmd_socket
lightningd-2 2026-02-26T11:29:47.758Z DEBUG   lightningd: testing /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/validating-lightning-signer/target/debug/remote_hsmd_socket
lightningd-1 2026-02-26T11:29:48.428Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_onchaind
lightningd-2 2026-02-26T11:29:49.170Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_onchaind
lightningd-1 2026-02-26T11:29:49.485Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_openingd
lightningd-2 2026-02-26T11:29:49.485Z DEBUG   lightningd: testing /Users/emanuele/cln-versions/vls-hsmd-test/lightningd/lightning_openingd
lightningd-1 2026-02-26T11:29:49.851Z DEBUG   hsmd: pid 81637, msgfd 70
lightningd-2 2026-02-26T11:29:49.851Z DEBUG   hsmd: pid 81638, msgfd 70
2026-02-26T11:29:49.861085Z  INFO vls-proxy/src/socket_main.rs:61: remote_hsmd_socket git_desc=v0.14.0-rc.2-38-gc54d3e3e starting
2026-02-26T11:29:49.861360Z  INFO vls-proxy/src/socket_main.rs:61: remote_hsmd_socket git_desc=v0.14.0-rc.2-38-gc54d3e3e starting
2026-02-26T11:29:49.862272Z  INFO vls-frontend/src/frontend.rs:161: frontend started
2026-02-26T11:29:49.862460Z  INFO vls-proxy/src/socket_main.rs:131: starting gRPC service on 127.0.0.1:64854
2026-02-26T11:29:49.862505Z  INFO vls-frontend/src/frontend.rs:161: frontend started
2026-02-26T11:29:49.862557Z  INFO /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:207: read loop 81637/3/0: start
2026-02-26T11:29:49.862642Z  INFO /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:215: read loop 81637/3/0 waiting for shutdown
2026-02-26T11:29:49.862687Z  INFO vls-proxy/src/socket_main.rs:131: starting gRPC service on 127.0.0.1:64850
2026-02-26T11:29:49.862854Z  INFO /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:207: read loop 81638/3/0: start
2026-02-26T11:29:49.862951Z  INFO vls-proxy/src/portfront.rs:91: waiting for signer_port to be ready
2026-02-26T11:29:49.862988Z  INFO /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:215: read loop 81638/3/0 waiting for shutdown
2026-02-26T11:29:49.863115Z  INFO vls-proxy/src/portfront.rs:91: waiting for signer_port to be ready
2026-02-26T11:29:49.863397Z ERROR /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:229: read loop 81637/3/0 saw error Protocol(TrailingBytes(9, 99)); ending
2026-02-26T11:29:49.863429Z  WARN /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:232: read loop 81637/3/0 terminated; triggering shutdown
lightningd: 2026-02-26T11:29:49.863517Z  INFO /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-1/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:218: read loop 81637/3/0 saw shutdown, calling exit
HSM sent unknown message type
2026-02-26T11:29:49.863637Z ERROR /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:229: read loop 81638/3/0 saw error Protocol(TrailingBytes(9, 99)); ending
2026-02-26T11:29:49.863667Z  WARN /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:232: read loop 81638/3/0 terminated; triggering shutdown
lightningd: 2026-02-26T11:29:49.863709Z  INFO /private/tmp/ltests-1uy95ld7/test_vls_simple_1/lightning-2/validating-lightning-signer/vls-proxy/src/grpc/signer_loop.rs:218: read loop 81638/3/0 saw shutdown, calling exit
HSM sent unknown message type
Time-out: can't find [re.compile('Server started with public key')] in logs
Time-out: can't find [re.compile('Server started with public key')] in logs
{'run_id': 285372585507352576, 'github_repository': 'ElementsProject/lightning', 'github_sha': 'b62be7967d323682b1086fb7876ca4ab7196a318', 'github_ref': None, 'github_ref_name': 'vls-hsmd-test', 'github_run_id': None, 'github_head_ref': None, 'github_run_number': None, 'github_base_ref': None, 'github_run_attempt': None, 'testname': 'test_vls_simple', 'start_time': 1772105332, 'end_time': 1772105447, 'outcome': 'fail'}
FAILEDLeaving base_dir /tmp/ltests-1uy95ld7 intact, it still has test sub-directories with failure details: ['test_vls_simple_1']

tests/test_pay.py::test_vls_simple ERROR

@enaples
Copy link
Copy Markdown
Collaborator Author

enaples commented Mar 4, 2026

test_vls_simple now passes.

WHAT SHOULD BE TAKEN INTO ACCOUNT

Having remote_hsmd_socket subdaemon that depends on env variables such as VLS_PORT, VLS_LSS, VLS_NETWORK, BITCOIND_RPC_URL makes we can only test only one vls-node each time since env vars are global. In order to have multiple nodes that uses vls, these parameters should be passed as an argument of the remote_hsmd_socket binary or added into lightning.conf but I didn't investigate that much if these solutions are feasible or not.

@cdecker
Copy link
Copy Markdown
Member

cdecker commented Mar 19, 2026

test_vls_simple now passes.

WHAT SHOULD BE TAKEN INTO ACCOUNT

Having remote_hsmd_socket subdaemon that depends on env variables such as VLS_PORT, VLS_LSS, VLS_NETWORK, BITCOIND_RPC_URL makes we can only test only one vls-node each time since env vars are global. In order to have multiple nodes that uses vls, these parameters should be passed as an argument of the remote_hsmd_socket binary or added into lightning.conf but I didn't investigate that much if these solutions are feasible or not.

Good catch, that we can only run a single node using the vls signer. However if we do not set the envvar, and set it in the proc.env field we can give each node their own signer. So don't set the envvar, set the proc.env as you spawn the signer in start() and it should wire things up correctly.

For reference:

shell env < env set in test coordinator < env set in test worker < env set by fixtures < env set on the proc

Copy link
Copy Markdown
Member

@cdecker cdecker left a comment

Choose a reason for hiding this comment

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

And it looks like I forgot to Submit my review once again. Apologies for the delay 🙏

Comment thread tests/fixtures.py Outdated
Comment thread tests/fixtures.py Outdated
Comment thread tests/fixtures.py Outdated
Comment thread tests/fixtures.py Outdated
Comment thread tests/vls.py Outdated
class ValidatingLightningSignerD(TailableProc):
def __init__(self, vlsd_dir, vlsd_port, vlsd_rpc_port, node_id, network):
TailableProc.__init__(self, vlsd_dir, verbose=True)
self.executable = env("REMOTE_SIGNER_CMD", 'vlsd2')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These are commonly called something_PATH cmd implies a full command including arguments.

Comment thread tests/test_pay.py Outdated

@pytest.mark.openchannel('v1')
@pytest.mark.openchannel('v2')
def test_vls_simple(node_factory):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We probably want a marker for opt-in here: @pytest.mark.vls
This allows us to pick only allowlisted tests in the VLS test, and gives us time to go through the tests and see if they are supposed to work with VLS.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Mark added

Comment thread tests/fixtures.py Outdated
}[self.vls_mode]

self.use_vlsd = subdaemon is not None
self.use_vls = use_vls is not None
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Technically this maps use_vls=False to self.use_vls=True

Comment thread tests/fixtures.py Outdated
self.daemon.env["VLS_LSS"] = os.environ.get("LSS_URI", "")
self.daemon.env["VLS_NETWORK"] = self.network
self.daemon.env["BITCOIND_RPC_URL"] = env("BITCOIND_RPC_URL", "http://rpcuser:rpcpass@127.0.0.1:{}".format(self.bitcoin.rpcport))
self.daemon.env["VLS_CLN_VERSION"] = env("VLS_CLN_VERSION", "v25.12-391-gc1dc506-modded")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Don't set a default value, error out if it is required and not set.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The default value will always be wrong, except for the one day the snapshot was taken.

Comment thread tests/fixtures.py Outdated
self.daemon.env["VLS_CLN_VERSION"] = env("VLS_CLN_VERSION", "v25.12-391-gc1dc506-modded")
self.daemon.env["BITCOIND_RPC_URL"] = env("BITCOIND_RPC_URL", f"http://{BITCOIND_CONFIG['rpcuser']}:{BITCOIND_CONFIG['rpcpassword']}@127.0.0.1:{self.bitcoin.rpcport}")
cln_version_str = subprocess.check_output([self.daemon.executable, "--version"]).decode('ascii').strip()
self.daemon.env["VLS_CLN_VERSION"] = env("VLS_CLN_VERSION", cln_version_str)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good fix.

Comment thread tests/fixtures.py
self.daemon.env["VLS_LSS"] = os.environ.get("LSS_URI", "")
self.daemon.env["VLS_NETWORK"] = self.network
self.daemon.env["VLS_LSS"] = env("LSS_URI", "")
self.daemon.env["VLS_NETWORK"] = env("VLS_NETWORK", self.network)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think these get inherited automatically, but good habit to explicitly pass them in.

@madelinevibes madelinevibes added this to the 26.06 milestone Apr 10, 2026
@enaples enaples force-pushed the vls-hsmd-test branch 3 times, most recently from b1ccf87 to 0e943c8 Compare April 23, 2026 08:01
@enaples enaples requested a review from cdecker April 23, 2026 11:56
@cdecker
Copy link
Copy Markdown
Member

cdecker commented May 4, 2026

Rebased on top of master to see if it passes.

@madelinevibes madelinevibes added PLEASE clear CI 🫠 Status::Ready for Review The work has been completed and is now awaiting evaluation or approval. labels May 4, 2026
Copy link
Copy Markdown
Member

@cdecker cdecker left a comment

Choose a reason for hiding this comment

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

Quite a nice change, thanks @enaples. I am not sure why the tests are failing, but it does seem like it is particularly dodgy when working with signer-specific things. Can you rebase and see why they fail? Otherwise I think this is all on the right track 👍

Comment thread tests/conftest.py Outdated
Comment on lines +45 to +50
if "vls" in item.keywords:
if not os.environ.get('REMOTE_SIGNER_PATH') and not os.environ.get('VLS_AUTO_BUILD'):
pytest.skip(
'VLS test skipped: set REMOTE_SIGNER_PATH (path to pre-built vlsd) '
'or VLS_AUTO_BUILD=1 to enable'
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This effectively partitions the tests into VLS and non-VLS. Whereas we want to have all tests run without VLS, but some be marked as also supporting VLS. We then create a nightly run that runs the test suite with VLS as the signer backend.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Got it, loud and clear. We didn't notice the nuance but now we think we (me and @ScuttoZ) fixed it.

Basically, in fixtures.py we defined another fixture that returns a boolean by checking if "vls" is among the markers, and uses that value as the option use_vls to spawn normal or VLS node. In this way, if "vls" marker isn't provided, use_vls will be set to False and the node will spawn as default.

Comment thread tests/fixtures.py Outdated
Comment on lines +71 to +76
elif use_vls is False:
self.vls_mode = "cln:native"
else:
# use_vls=None (default) falls back to the VLS_MODE env var.
# Setting this env var causes all nodes use the same mode
self.vls_mode = env("VLS_MODE", "cln:native")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good point, though I doubt we will want that amount of flexibility. It's already rather confusing: either we have a VLS signer or we have a native one, now if we selectively use VLS on certain nodes we would also need to indicate which ones, and which other ones should be using the native one.

Let's keep it all or nothing for now, and rather mark a couple of tests and non-VLS only that may work with one side as VLS, but not others.

Comment thread tests/fixtures.py
# FIXME: VLS doesn't implement WIRE_HSMD_SIGN_SPLICE_TX, so lightningd
# would fatal() during hsm_init if OPT_SPLICE (bit 62) is offered.
# Strip the optional splice bit (63 = OPTIONAL_FEATURE(62)).
self.daemon.opts["dev-force-features"] = "-63"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should likely be removed pretty soon as we are working with VLS to add support. Then once that support lands, we can go back to marking entire tests as VLS-enabled or not.

Comment thread tests/utils.py
import bitstring
from pyln.client import Millisatoshi
from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND
from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND, BITCOIND_CONFIG # noqa: F401
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is this change for? Wildcard import?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Exactly, this is required for the BITCOIN_RPC_URL env variable used by VLS

 self.daemon.env["BITCOIND_RPC_URL"] = env(
                "BITCOIND_RPC_URL",
                f"http://{BITCOIND_CONFIG['rpcuser']}:{BITCOIND_CONFIG['rpcpassword']}@127.0.0.1:{self.bitcoin.rpcport}",
        )

Comment thread tests/vls.py Outdated
logging.info(f"Building vlsd in {vlsd_dir}")
run(["cargo", "build", "--features", "developer"],
cwd=vlsd_dir, check=True, timeout=600)
return (vlsd_dir / "target" / "debug" / "vlsd").resolve()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Quietly assumes CARGO_TARGET_DIR is not set.

Comment thread tests/vls.py Outdated
self.datadir.mkdir(exist_ok=True, parents=True)

self.bin_dir = str(_resolve_executable(self.datadir))
self.executable = self.bin_dir + "/vlsd"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
self.executable = self.bin_dir + "/vlsd"
self.executable = self.bin_dir / "vlsd"

pathlib.Path works great for path manipulation.

Comment thread tests/vls.py Outdated
# state between them.
self.env["ALLOWLIST"] = env(
"REMOTE_SIGNER_ALLOWLIST",
"contrib/remote_hsmd/TESTING_ALLOWLIST",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is relative to the CLN repo, not the VLS repo, so if the default value is chosen it will most likely point to a non-existent location.

Comment thread tests/vls.py
Comment on lines +69 to +70
f"--rpc-user=bitcoind",
f"--rpc-pass=bitcoind"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The linter will most likely not like the f-strings without placeholders.

enaples added 5 commits May 8, 2026 13:59
Add a `use_vls` per-node option to `LightningNode` that spawns a
`vlsd` signer process per node and routes hsmd through
`remote_hsmd_socket`. Each node gets its own datadir, ports, and
signer env so multiple signers can run in parallel.

- New `ValidatingLightningSignerD` (tests/vls.py) wraps vlsd as a
  TailableProc; resolves the binary from `REMOTE_SIGNER_PATH` or
  builds it via `VLS_AUTO_BUILD=1`.
- `NodeFactory` is extended so `use_vls` reaches the node ctor as a
  kwarg instead of being forwarded as a lightningd CLI flag.
- `dev-force-features=-63` is set on VLS-backed nodes to strip the
  optional splice bit, since VLS does not implement
  WIRE_HSMD_SIGN_SPLICE_TX and lightningd would otherwise fatal()
  during hsm_init.
- `VLS_AUTOAPPROVE=1` is set on the vlsd process env so invoice
  preapproval doesn't decline payments in tests.
- Three smoke tests added: send/receive/route through a VLS-backed
  node.
By default the full test suite  (including tests marked `vls`) now
runs with `use_vls=False`, so contributors without a VLS signer can run
everything end-to-end. The signer is exercised only when the session is
started with exactly `-m vls`; in that case pytest aborts up front
unless `REMOTE_SIGNER_PATH` or `VLS_AUTO_BUILD` is set (the two are
mutually exclusive).

- conftest.py: gate the env-var check in pytest_configure on the
  `-m vls` markexpr and drop the per-test skip in pytest_runtest_setup.
- fixtures.py: expose a `use_vls` fixture that resolves to True only
  when `-m vls` is active.
- test_pay.py: thread that fixture through the vls-marked tests so
  `{'use_vls': use_vls}` collapses to False in default runs.
…-relative path

The previous default `contrib/remote_hsmd/TESTING_ALLOWLIST` was resolved
relative to vlsd's cwd (the VLS repo), not the CLN repo where the file
historically lived, so it silently pointed at a non-existent location.

Drop the fallback: if `REMOTE_SIGNER_ALLOWLIST` is unset, log a warning
and let vlsd start without an allowlist, leaving it to the operator to
provide an absolute path when one is needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PLEASE clear CI 🫠 Status::Ready for Review The work has been completed and is now awaiting evaluation or approval.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants