Skip to content

Commit 9f754a1

Browse files
committed
test(py): Add a dummy LSPS policy plugin, and an LSPS node fixture
We need something to test against, the dummy plugin just returns a fixed result, so the `cln-lsps-servive` plugin has something to work against.
1 parent ef45eea commit 9f754a1

File tree

4 files changed

+119
-3
lines changed

4 files changed

+119
-3
lines changed
Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
1+
from pathlib import Path
12
from .scheduler import Scheduler
23

4+
5+
def get_plugins_dir():
6+
"""Get the path to the plugins directory.
7+
8+
This works both when running from source (where plugins is a sibling
9+
of gltesting) and when installed via pip (where both gltesting and
10+
plugins are installed into site-packages).
11+
12+
Returns:
13+
Path: The absolute path to the plugins directory
14+
15+
Raises:
16+
FileNotFoundError: If the plugins directory cannot be found
17+
"""
18+
# Get the directory containing this __init__.py file (gltesting/)
19+
package_dir = Path(__file__).parent
20+
21+
# Try to find plugins as a sibling directory
22+
# This handles both source and installed cases since both directories
23+
# are installed at the same level
24+
plugins_dir = package_dir.parent / "plugins"
25+
26+
if plugins_dir.exists() and plugins_dir.is_dir():
27+
return plugins_dir
28+
29+
raise FileNotFoundError(
30+
f"Could not find plugins directory. Expected at: {plugins_dir}"
31+
)
32+
33+
334
__all__ = [
4-
Scheduler
35+
"Scheduler",
36+
"get_plugins_dir",
537
]

libs/gl-testing/gltesting/fixtures.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Pytest fixtures
2+
from rich.pretty import pprint
23
import tempfile
34
from .scheduler import Scheduler
45
from gltesting.clients import Clients, Client
@@ -224,12 +225,38 @@ def grpc_web_proxy(scheduler, grpc_test_server):
224225

225226
@pytest.fixture
226227
def node_grpc_web_proxy(scheduler):
227-
"""A grpc-web proxy that knows how to talk to nodes.
228-
"""
228+
"""A grpc-web proxy that knows how to talk to nodes."""
229229
p = GrpcWebProxy(scheduler=scheduler, grpc_port=0)
230230
p.handler_cls = NodeHandler
231231
p.start()
232232

233233
yield p
234234

235235
p.stop()
236+
237+
238+
@pytest.fixture
239+
def lsps_server(node_factory):
240+
"""Provision and start an LSPs server."""
241+
from gltesting import get_plugins_dir
242+
243+
policy_plugin = get_plugins_dir() / "lsps2_policy.py"
244+
245+
lsp = node_factory.get_node(
246+
options={
247+
"experimental-lsps2-service": None,
248+
"experimental-lsps2-promise-secret": "A" * 64,
249+
"important-plugin": policy_plugin,
250+
"disable-plugin": "cln-grpc",
251+
}
252+
)
253+
254+
# Most of the params below are ignored, this is just a smoke test either way
255+
pprint(lsp.rpc.lsps2_policy_getpolicy())
256+
pprint(
257+
lsp.rpc.lsps2_policy_getchannelcapacity(
258+
init_payment_size=10**6, scid="1x1x1", opening_fee_params=None
259+
)
260+
)
261+
262+
yield lsp
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python3
2+
"""A simple implementation of a LSPS2 compatible policy plugin. It is the job
3+
of this plugin to deliver a fee options menu to the LSPS2 service plugin.
4+
"""
5+
6+
from pyln.client import Plugin
7+
from datetime import datetime, timedelta, timezone
8+
9+
10+
plugin = Plugin()
11+
12+
13+
@plugin.method("lsps2-policy-getpolicy")
14+
def lsps2_policy_getpolicy(request):
15+
"""Returns an opening fee menu for the LSPS2 plugin."""
16+
now = datetime.now(timezone.utc)
17+
18+
# Is ISO 8601 format "YYYY-MM-DDThh:mm:ss.uuuZ"
19+
valid_until = (now + timedelta(hours=1)).isoformat().replace("+00:00", "Z")
20+
21+
return {
22+
"policy_opening_fee_params_menu": [
23+
{
24+
"min_fee_msat": "1000",
25+
"proportional": 1000,
26+
"valid_until": valid_until,
27+
"min_lifetime": 2000,
28+
"max_client_to_self_delay": 2016,
29+
"min_payment_size_msat": "1000",
30+
"max_payment_size_msat": "100000000",
31+
},
32+
{
33+
"min_fee_msat": "1092000",
34+
"proportional": 2400,
35+
"valid_until": valid_until,
36+
"min_lifetime": 1008,
37+
"max_client_to_self_delay": 2016,
38+
"min_payment_size_msat": "1000",
39+
"max_payment_size_msat": "1000000",
40+
},
41+
]
42+
}
43+
44+
45+
@plugin.method("lsps2-policy-getchannelcapacity")
46+
def lsps2_policy_getchannelcapacity(request, init_payment_size, scid, opening_fee_params):
47+
"""Returns an opening fee menu for the LSPS2 plugin."""
48+
return {"channel_capacity_msat": 100000000}
49+
50+
51+
plugin.run()

libs/gl-testing/pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,10 @@ build-backend = "hatchling.build"
3737
[tool.hatch.build]
3838
include = [
3939
"gltesting",
40+
"plugins",
41+
]
42+
exclude = [
43+
"**/.#*",
44+
"**/*~",
45+
"**/*.swp",
4046
]

0 commit comments

Comments
 (0)