from fixtures import * # noqa: F401,F403 from pyln.testing.utils import RUST from utils import only_one import os import pytest import unittest RUST_PROFILE = os.environ.get("RUST_PROFILE", "debug") def test_lsps_service_disabled(node_factory): """By default we disable the LSPS service plugin. It should only be enabled if we explicitly set the config option `lsps-service=True`. """ l1 = node_factory.get_node(1) l1.daemon.is_in_log("`lsps-service` not enabled") @unittest.skipUnless(RUST, 'RUST is not enabled') def test_lsps0_listprotocols(node_factory): l1, l2 = node_factory.get_nodes( 2, opts=[ {"experimental-lsps-client": None}, { "experimental-lsps2-service": None, "experimental-lsps2-promise-secret": "0" * 64, }, ], ) # We don't need a channel to query for lsps services node_factory.join_nodes([l1, l2], fundchannel=False) res = l1.rpc.lsps_listprotocols(lsp_id=l2.info["id"]) assert res def test_lsps2_enabled(node_factory): l1, l2 = node_factory.get_nodes( 2, opts=[ {"experimental-lsps-client": None}, { "experimental-lsps2-service": None, "experimental-lsps2-promise-secret": "0" * 64, }, ], ) node_factory.join_nodes([l1, l2], fundchannel=False) res = l1.rpc.lsps_listprotocols(lsp_id=l2.info["id"]) assert res["protocols"] == [2] def test_lsps2_getinfo(node_factory): plugin = os.path.join(os.path.dirname(__file__), "plugins/lsps2_policy.py") l1, l2 = node_factory.get_nodes( 2, opts=[ {"experimental-lsps-client": None}, { "experimental-lsps2-service": None, "experimental-lsps2-promise-secret": "0" * 64, "plugin": plugin, }, ] ) node_factory.join_nodes([l1, l2], fundchannel=False) res = l1.rpc.lsps_lsps2_getinfo(lsp_id=l2.info["id"]) assert res["opening_fee_params_menu"] def test_lsps2_buy(node_factory): # We need a policy service to fetch from. plugin = os.path.join(os.path.dirname(__file__), "plugins/lsps2_policy.py") l1, l2 = node_factory.get_nodes( 2, opts=[ {"experimental-lsps-client": None}, { "experimental-lsps2-service": None, "experimental-lsps2-promise-secret": "0" * 64, "plugin": plugin, }, ] ) # We don't need a channel to query for lsps services node_factory.join_nodes([l1, l2], fundchannel=False) res = l1.rpc.lsps_lsps2_getinfo(lsp_id=l2.info["id"]) params = res["opening_fee_params_menu"][0] res = l1.rpc.lsps_lsps2_buy(lsp_id=l2.info["id"], opening_fee_params=params) assert res def test_lsps2_buyjitchannel_no_mpp_var_invoice(node_factory, bitcoind): """Tests the creation of a "Just-In-Time-Channel" (jit-channel). At the beginning we have the following situation where l2 acts as the LSP (LSP) l1 l2----l3 l1 now wants to get a channel from l2 via the lsps2 jit-channel protocol: - l1 requests a new jit channel form l2 - l1 creates an invoice based on the opening fee parameters it got from l2 - l3 pays the invoice - l2 opens a channel to l1 and forwards the payment (deducted by a fee) eventualy this will result in the following situation (LSP) l1----l2----l3 """ # We need a policy service to fetch from. plugin = os.path.join(os.path.dirname(__file__), "plugins/lsps2_policy.py") l1, l2, l3 = node_factory.get_nodes( 3, opts=[ {"experimental-lsps-client": None}, { "experimental-lsps2-service": None, "experimental-lsps2-promise-secret": "0" * 64, "plugin": plugin, "fee-base": 0, # We are going to deduct our fee anyways, "fee-per-satoshi": 0, # We are going to deduct our fee anyways, }, {}, ], ) # Give the LSP some funds to open jit-channels addr = l2.rpc.newaddr()["bech32"] bitcoind.rpc.sendtoaddress(addr, 1) bitcoind.generate_block(1) node_factory.join_nodes([l3, l2], fundchannel=True, wait_for_announce=True) node_factory.join_nodes([l1, l2], fundchannel=False) chanid = only_one(l3.rpc.listpeerchannels(l2.info["id"])["channels"])[ "short_channel_id" ] inv = l1.rpc.lsps_jitchannel( lsp_id=l2.info["id"], amount_msat="any", description="lsp-jit-channel-0", label="lsp-jit-channel-0", ) assert inv dec = l3.rpc.decode(inv["bolt11"]) assert dec routehint = only_one(only_one(dec["routes"])) amt = 10000000 route = [ {"amount_msat": amt, "id": l2.info["id"], "delay": 14, "channel": chanid}, { "amount_msat": amt, "id": l1.info["id"], "delay": 8, "channel": routehint["short_channel_id"], }, ] l3.rpc.sendpay( route, dec["payment_hash"], payment_secret=inv["payment_secret"], bolt11=inv["bolt11"], partid=0, ) res = l3.rpc.waitsendpay(dec["payment_hash"]) assert res["payment_preimage"] # l1 should have gotten a jit-channel. chs = l1.rpc.listpeerchannels()["channels"] assert len(chs) == 1 def test_lsps2_non_approved_zero_conf(node_factory, bitcoind): """Checks that we don't allow zerof_conf channels from an LSP if we did not approve it first. """ # We need a policy service to fetch from. plugin = os.path.join(os.path.dirname(__file__), "plugins/lsps2_policy.py") l1, l2, l3 = node_factory.get_nodes( 3, opts=[ {"experimental-lsps-client": None}, { "experimental-lsps2-service": None, "experimental-lsps2-promise-secret": "0" * 64, "plugin": plugin, "fee-base": 0, # We are going to deduct our fee anyways, "fee-per-satoshi": 0, # We are going to deduct our fee anyways, }, {"disable-mpp": None}, ], ) # Give the LSP some funds to open jit-channels addr = l2.rpc.newaddr()["bech32"] bitcoind.rpc.sendtoaddress(addr, 1) bitcoind.generate_block(1) node_factory.join_nodes([l3, l2], fundchannel=True, wait_for_announce=True) node_factory.join_nodes([l1, l2], fundchannel=False) fee_opt = l1.rpc.lsps_lsps2_getinfo(lsp_id=l2.info["id"])[ "opening_fee_params_menu" ][0] buy_res = l1.rpc.lsps_lsps2_buy(lsp_id=l2.info["id"], opening_fee_params=fee_opt) hint = [ [ { "id": l2.info["id"], "short_channel_id": buy_res["jit_channel_scid"], "fee_base_msat": 0, "fee_proportional_millionths": 0, "cltv_expiry_delta": buy_res["lsp_cltv_expiry_delta"], } ] ] bolt11 = l1.dev_invoice( amount_msat="any", description="lsp-invoice-1", label="lsp-invoice-1", dev_routes=hint, )["bolt11"] with pytest.raises(ValueError): l3.rpc.pay(bolt11, amount_msat=10000000) # l1 shouldn't have a new channel. chs = l1.rpc.listpeerchannels()["channels"] assert len(chs) == 0