Commit graph

22 commits

Author SHA1 Message Date
Rusty Russell
54a5eddee7 pytest: mark xpay real gossip test as slow
```
____________________ ERROR at teardown of test_xpay_maxfee _____________________
...
            # Format a nice list of everything that went wrong and raise an exception
            request.node.has_errors = True
>           raise ValueError(str(errors))
E           ValueError: 
E           Node errors:
E            - lightningd-1: Node exited with return code 1
E           Global errors:
```

And:

```
    @unittest.skipIf(TEST_NETWORK != 'regtest', 'too dusty on elements')
    def test_xpay_maxfee(node_factory, bitcoind, chainparams):
        """Test which shows that we don't excees maxfee"""
        outfile = tempfile.NamedTemporaryFile(prefix='gossip-store-')
        subprocess.check_output(['devtools/gossmap-compress',
                                 'decompress',
                                 '--node-map=3301=022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59',
                                 'tests/data/gossip-store-2024-09-22.compressed',
                                 outfile.name]).decode('utf-8').splitlines()
        AMOUNT = 100_000_000
    
        # l2 will warn l1 about its invalid gossip: ignore.
        # We throttle l1's gossip to avoid massive log spam.
>       l1, l2 = node_factory.line_graph(2,
                                         # This is in sats, so 1000x amount we send.
                                         fundamount=AMOUNT,
                                         opts=[{'gossip_store_file': outfile.name,
                                                'subdaemon': 'channeld:../tests/plugins/channeld_fakenet',
                                                'allow_warning': True,
                                                'dev-throttle-gossip': None},
                                               {'allow_bad_gossip': True}])

tests/test_xpay.py:509: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
contrib/pyln-testing/pyln/testing/utils.py:1720: in line_graph
    nodes = self.get_nodes(num_nodes, opts=opts)
contrib/pyln-testing/pyln/testing/utils.py:1602: in get_nodes
    return [j.result() for j in jobs]
contrib/pyln-testing/pyln/testing/utils.py:1602: in <listcomp>
    return [j.result() for j in jobs]
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/concurrent/futures/_base.py:458: in result
    return self.__get_result()
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/concurrent/futures/_base.py:403: in __get_result
    raise self._exception
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/concurrent/futures/thread.py:58: in run
    result = self.fn(*self.args, **self.kwargs)
contrib/pyln-testing/pyln/testing/utils.py:1653: in get_node
    node.start(wait_for_bitcoind_sync)
contrib/pyln-testing/pyln/testing/utils.py:1015: in start
    self.daemon.start(stderr_redir=stderr_redir)
contrib/pyln-testing/pyln/testing/utils.py:671: in start
    self.wait_for_log("Server started with public key")
contrib/pyln-testing/pyln/testing/utils.py:355: in wait_for_log
    return self.wait_for_logs([regex], timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pyln.testing.utils.LightningD object at 0x7f27ab586c20>
regexs = ['Server started with public key'], timeout = 180

    def wait_for_logs(self, regexs, timeout=TIMEOUT):
        """Look for `regexs` in the logs.
    
        The logs contain tailed stdout of the process. We look for each regex
        in `regexs`, starting from `logsearch_start` which normally is the
        position of the last found entry of a previous wait-for logs call.
        The ordering inside `regexs` doesn't matter.
    
        We fail if the timeout is exceeded or if the underlying process
        exits before all the `regexs` were found.
    
        If timeout is None, no time-out is applied.
        """
        logging.debug("Waiting for {} in the logs".format(regexs))
        exs = [re.compile(r) for r in regexs]
        start_time = time.time()
        while True:
            if self.logsearch_start >= len(self.logs):
                if not self.logs_catchup():
                    time.sleep(0.25)
    
                if timeout is not None and time.time() > start_time + timeout:
                    print("Time-out: can't find {} in logs".format(exs))
                    for r in exs:
                        if self.is_in_log(r):
                            print("({} was previously in logs!)".format(r))
>                   raise TimeoutError('Unable to find "{}" in logs.'.format(exs))
E                   TimeoutError: Unable to find "[re.compile('Server started with public key')]" in logs.
```

gossipd (and other plugins) simply take too long to digest the gossmap under valgrind.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-01-27 11:07:04 +10:30
michael1011
060368bb0a xpay: add maxdelay parameter
Changelog-Added: Plugins: `xpay` now supports a `maxdelay` parameter for better `xpay-handle-pay` compatibility.
2025-01-22 12:19:47 -08:00
Rusty Russell
2c8d9d0deb pytest: actually test xpay/pay return similarity.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-12-18 14:04:14 +10:30
Rusty Russell
84f30b12f7 pytest: bonus test to make sure xpay uses zeroconf channels correctly.
It needs to use the channel alias here, and it does.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-12-17 15:59:30 +10:30
Rusty Russell
a2f58a28ba lightningd: injectpaymentonion can use scids of unannounced channels.
Cut & paste from the forwarding code, where we don't let onions use the
unannounced scids.  Obviously local commands can use them.

Reported-by: @michael1011
Changelog-Fixed: JSON-RPC: xpay now works through unannounced channels.
2024-12-17 15:59:30 +10:30
Rusty Russell
92c45712d2 pytest: test xpay using unannounced channels.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-12-17 15:59:30 +10:30
Rusty Russell
d26ea6673d xpay: more accurately reflect pay when xpay-handle-pay is set.
Note that the slight code reorder changes the JSON order, which is generally
undefined, but our doc checker is very strict!

Changelog-Changed: `xpay` now gives the same JSON success return as documented by `pay` when `xpay-handle-pay` is set.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Fixes: https://github.com/ElementsProject/lightning/issues/7923
2024-12-17 15:49:03 +10:30
Rusty Russell
428c76068c xpay: emulate maxfeepercent and exemptfee when xpay-handle-pay used
maxfeepercent is use by Zeus, so let's make that work.

maxfee is more precise, so it's the only xpay option (maxfee was added
to pay later).

[ Fix to ppm logic by Lagrang3, thanks! --RR ]

Fixes: https://github.com/ElementsProject/lightning/issues/7926
Changelog-Changed: JSON-RPC: With `xpay-handle-pay` set, xpay will now be used even if `pay` uses maxfeeprecent or exemptfee parameters (e.g. Zeus)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-12-17 10:54:31 +10:30
Rusty Russell
cf22762c8f xpay: tell injectpaymentonion what the amount being delivered to destination is.
This means that it gets shown in listsendpays: omitting this broke spark, apparently!

Changelog-Changed: `xpay` now populates more fields, so `listsendpays` and `listpays` show `destination` and `amount_msat` fields for xpay payments.
Fixes: https://github.com/ElementsProject/lightning/issues/7881
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-12-17 08:14:45 +10:30
Rusty Russell
113156858b xpay: don't excees maxfee *overall*.
We were handing "maxfee" to every getroutes call, even if we had already
used some of the fees.

Reported-by: @daywalker90
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: xpay is new this release.
2024-12-02 14:31:11 +10:30
Rusty Russell
d0b470618e pytest: test for maxfee compliance.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-12-02 14:31:11 +10:30
Rusty Russell
2bf1053cdb offers: update block height correctly.
As we can see from the previous test, l3 tells us why it rejected the payment:

```
lightningd-3 2024-11-19T03:56:27.151Z DEBUG   022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59-chan#1: Failing HTLC because of an invalid payload (TLV 10 pos 104): cltv_expiry 136 > payment_constraint 130
```

It turns out, we were not updating the block height in the plugin!

Without this, when we create a (non-dummy) blinded path we set a
too-low CLTV restriction, and it doesn't work after a few blocks!

Note we were actually triggering this error in the xpay tests!

Reported-by: Vincenzo Palazzo
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Offers: Receiving bolt12 payments where we have no public channels would fail a few blocks after startup.
2024-11-20 12:29:27 +01:00
Rusty Russell
0cc52bc281 pytest: don't set experimental-offers in tests: it's the default now.
And about to be deprecated.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 10:42:54 +01:00
Rusty Russell
05fbcb4d9b xpay: make sure to call preapproveinvoice!
This is required for VLS which wants to know (and potentially decline) invoices
we're trying to pay.

As a nice side effect, our "check" command for xpay now does much more thorough
checking of arguments.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
2c15dc0e5b xpay: make self-pay work.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
229fc3f2b4 xpay: make the xpay layer persistent.
As the first user of a persistent layer, this tripped tests which
assumed the datastore would be empty!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
c715253af7 xpay: option to steal easy commands from pay.
Note: won't work with grpc (or probably other tools), since the output
is different.  But good for testing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Config: option `xpay-handle-pay` can be used to call xpay when pay is used in many cases (but output is different from pay!)
2024-11-18 11:03:26 +10:30
Rusty Russell
dd4d3940b1 xpay: implement partial payments.
Explicitly tell xpay to only make part of a payment.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
47318a7875 xpay: add deadline.
We promised this in the schema originally, now support it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
06a9aa8907 pytest: test xpay with channeld_fakenet to pay top 100 nodes.
We also put broken status messages for invalid CLTVs and amounts in onions,
to catch them in CI.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
7c2407ef48 xpay: new plugin which uses askrene, injectpaymentonion.
Changelog-Added: Plugins: cln-xpay, with associated `xpay` command for payments.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
75362d21c5 channeld_fakenet: fake channeld to simulate network given a gossmap_store.
Our gossmap_store uncompresser generates nodeids with well-known
privkeys, so we can decrypt and respond to HTLCs sent to such nodes.
By replacing channeld with a fake, we can connect a node to another
node, but then once the channel is established, allow payments to be
sent into the generated network, and respond appropriately.

This minimal version handles MPP timeouts, but doesn't insert any
delays or runtime capacity for channels.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: Testing only
2024-11-06 21:17:36 +10:30