fundwallet() actually mines a block, putting our count out. If we see
both blocks at once, we will say "52" blocks instead of "51":
```
2025-05-02T05:28:40.5315155Z have_forgotten = l2.daemon.is_in_log(
2025-05-02T05:28:40.5315650Z r"UNUSUAL {}-chan#1: Forgetting channel: It has been 51 blocks without the funding transaction ".format(l1.info['id'])
2025-05-02T05:28:40.5316105Z )
2025-05-02T05:28:40.5316263Z
2025-05-02T05:28:40.5316417Z if dopay:
2025-05-02T05:28:40.5316616Z assert not have_forgotten
2025-05-02T05:28:40.5317056Z assert set([c['peer_id'] for c in l2.rpc.listpeerchannels()["channels"]]) == set([l1.info['id'], l3.info['id']])
2025-05-02T05:28:40.5317477Z else:
2025-05-02T05:28:40.5317662Z > assert have_forgotten
2025-05-02T05:28:40.5317887Z E assert None
```
```
0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-chan#1: Forgetting channel: It has been 52 blocks without the funding transaction 0bb0579df6b1d983dda49dad47513afc71696c9d5bea3c8b955ba4b76bb053de getting deeply confirmed. We are fundee and can forget channel without loss of funds.
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We were supposed to put the sqlite db in a different directory, but
the test was wrong! So occasionally we would crash with:
```
Failed to commit DB transaction: Failed to commit a transaction: disk I/O error
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This finally happened on my local build machine, so I tracked it down using
py-spy, `apt-get install python3-dbg` and `py-local`.
Turns out the dev-memleak command was hanging, and the processes were stuck in
SIGSTOP. There are only two places we send that, and sure enough, this was
the test which was running at the time.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This may be useful for their recovery, though they should see the spend onchain.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: We now reply to `channel_reestablish` even on long-closed channels.
This was always false. peer_start_channeld was called in various places
with the argument "NULL" instead of "false", which unfortunately compilers
didn't complain about :(
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Michael of Boltz told me this long ago, that when fees spiked some of their clients' opens got stuck. After two weeks their node forgot them, and when fees came back down the opens still failed. Unfortunately, I can't see an issue for this!
We can give some grace: we don't want to waste too many resources, but 100 channels is nothing.
The test needs to be adjusted to have *two* slow open channels, now.
Changelog-Changed: Protocol: we won't forget still-opening channels after 2016 blocks, unless there are more than 100.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
It makes the schema simpler, and indeed, expressable by GRPC.
Changelog-Added: JSON-RPC: `wait` now has separate `invoices`, `forwards` and `sendpays` objects for each subsystem.
Changelog-Deprecated: JSON-RPC: `wait` reply `details` object: use subsytem specific object instead.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Testing parenting handling revealed several issues:
1. By calling "trace_span_start" when CLN_TRACEPARENT is set produces a bogus
entry, for which the span_id is overwritten so we never end it.
2. We don't need to close the remote parent when we close the first child: in
fact, this causes the remaining traces to be detached from the parent!
3. Suspension should return current to the parent, not to NULL.
Now the traces balance as we expect.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
get_channel_scid() returns the *first* channel, and we want all the channels.
So they may not actually be all visible in gossip.
```
@unittest.skipIf(TEST_NETWORK == 'liquid-regtest', "broken for some reason")
def test_hardmpp2(node_factory, bitcoind):
"""Credits to @daywalker90 for this test case."""
opts = {"disable-mpp": None, "fee-base": 0, "fee-per-satoshi": 10}
l1, l2, l3 = node_factory.get_nodes(3, opts=opts)
start_channels(
[
(l1, l2, 100_000),
(l1, l2, 200_000),
(l1, l2, 300_000),
(l1, l2, 400_000),
(l2, l3, 100_000),
(l2, l3, 200_000),
(l2, l3, 300_000),
(l2, l3, 600_000),
]
)
# FIXME: changing the last channel from 600k to 400k will fail the test due
# to l2 not accepting to forward any amount above 200k with error:
# CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED, still investigating
inv = l3.rpc.invoice("800000sat", "inv", "description")
> l1.rpc.call("renepay", {"invstring": inv["bolt11"]})
tests/test_renepay.py:797:
...
elif "error" in resp:
> raise RpcError(method, payload, resp['error'])
E pyln.client.lightning.RpcError: RPC call failed: method: renepay, payload: {'invstring': 'lnbcrt8m1pnl3zfksp54n6vhkrcj0nkn2uqhf232v62539048u2ree4g9ssytm47gasgctspp58twj5xf4h57s4h0rhy55p5q6nry36glummjexsf4lc446je7y27qdqjv3jhxcmjd9c8g6t0dcxqyjw5qcqp9rzjqgkjyd3q5dv6gllh77kygly9c3kfy0d9xwyjyxsq2nq3c83u5vw4jqqqvuqqqzqqqqqqqqqqqqqqqzsqqcrzjqgkjyd3q5dv6gllh77kygly9c3kfy0d9xwyjyxsq2nq3c83u5vw4jqqqvuqqqpcqqqqqqqqqqqqqqzsqqcrzjqgkjyd3q5dv6gllh77kygly9c3kfy0d9xwyjyxsq2nq3c83u5vw4jqqqvuqqqqgqqqqqqqqqqqqqqzsqqcrzjqgkjyd3q5dv6gllh77kygly9c3kfy0d9xwyjyxsq2nq3c83u5vw4jqqqvuqqqpqqqqqqqqqqqqqqqzsqqc9qxpqysgqtgxcneu0u7xvetgh2kqmey86jssweneat5vx3fppuaphl9v9jweqa2ymczg9klau9jmsm6pm7m3cd28pggp7avuukjqxg63wy2vuvtcpggz4vt'}, error: {'code': 205, 'message': "minflow couldn't find a feasible flow: failed to find a feasible flow: find_admissible_path failed"}
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
The handshake targets were based on a false premise: that it is
impossible for any fuzzer to generate valid Act 1 or 2 packets. Niklas
Gogge proved this premise incorrect using AFL++ with the CMPLOG feature,
which enabled AFL++ to generate such valid packets.
We modify the targets to allow the scenario where the fuzzer finds these
valid packets and add the inputs AFL++ found to the corpus.
The cryptofuzz target was based on a false premise: that it is
impossible for any fuzzer to generate a valid ciphertext+MAC for the
decrypt function. Niklas Gogge proved this premise incorrect using AFL++
with the CMPLOG feature, which enabled AFL++ to generate such valid
messages.
We remove the assertions requiring decryption to fail and add the inputs
AFL++ found to the corpus.
This can happen with 24.11 and later. We scan back to exposed channel
opens, or that release.
The BROKEN log messages cause some tests to fail, so we fix those.
Fixes: https://github.com/ElementsProject/lightning/issues/8169
Changelog-Fixed: wallet: rescan for missing close outputs (can happen if peer doesn't support option_shutdown_anysegwit)
We select the close key index at opening time, but the non-DF code didn't correctly register the
address as possibly used for P2WPKH for older nodes.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: wallet: we could miss our own returned outputs on mutual closes if peer doesn't support option_shutdown_anysegwit (you will still need to rescan after update, if this happened to you!)
Reported-by: Grubles
1. Peer has to not support option_shutdown_anysegwit.
2. We have to restart between opening and closing the channel.
3. We won't see the to-us output, since it's p2wpkh not p2tr.
This bug was introduced in 24.11.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We handed NULL as the logcb, resulting in a very uninformative crash:
```
2025-03-14T03:46:36.447Z INFO lightningd: Server started with public key 03d67f36c4f81789e2fe425028bacc96b199813eae426c517f589a45f1136c1fe5, alias Jubilee (color #dc42f4) and lightningd v25.02
topology: FATAL SIGNAL 11 (version v25.02)
0x560037f64aad send_backtrace
common/daemon.c:33
0x560037f64b49 crashdump
common/daemon.c:78
0x7f6c41ff351f ???
./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0x0 ???
???:0
```
Changelog-Fixed: `topology` crash on invoice creation if a peer had a really high feerate.
Fixes: https://github.com/ElementsProject/lightning/issues/8156
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We reconnect from l3->l2, but l2 is also trying to reconnect and
we can race:
```
# Now try when l3 uses scid for entry point of blinded path.
l3.stop()
l3.daemon.opts['dev-invoice-bpath-scid'] = None
l3.start()
> l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
tests/test_pay.py:5667:
...
> raise RpcError(method, payload, resp['error'])
E pyln.client.lightning.RpcError: RPC call failed: method: connect, payload: {'id': '022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59', 'host': 'localhost', 'port': 33557}, error: {'code': 402, 'message': 'disconnected during connection'}
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
By submitting them all at once, rather than serially, we should *definitely* hit the
ratelimit. We can also reduce the timeout (from 60 seconds) to speed the test up.
```
@pytest.mark.slow_test
def test_onionmessage_ratelimit(node_factory):
l1, l2 = node_factory.line_graph(2, fundchannel=False,
opts={'allow_warning': True})
offer = l2.rpc.call('offer', {'amount': '2msat',
'description': 'simple test'})
# Hopefully we can do this fast enough to reach ratelimit!
> with pytest.raises(RpcError, match="Timeout waiting for response"):
E Failed: DID NOT RAISE <class 'pyln.client.lightning.RpcError'>
tests/test_pay.py:5825: Failed
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We play with directory permissions, but sqlites needs that, and sometimes (due to a timer, perhaps?)
it gets really upset about it:
```
lightningd-1 2025-03-16T23:29:58.506Z INFO lightningd: Server started with public key 0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518, alias JUNIORBEAM-f91eb11-modded (color #0266e4) and lightningd f91eb11-modded
lightningd-1 2025-03-16T23:29:58.617Z DEBUG lightningd: Adding block 101: 55af171ade598f8c4f9a494eaaffe6b9f5ea64c7b0f3b273694148adf7ad7385
lightningd-1 2025-03-16T23:29:58.752Z TRACE lightningd: Calling rpc_command hook of plugin cln-xpay
lightningd-1 2025-03-16T23:29:58.764Z TRACE lightningd: Plugin cln-xpay returned from rpc_command hook call
lightningd-1 2025-03-16T23:29:58.784Z TRACE lightningd: Calling rpc_command hook of plugin cln-xpay
lightningd-1 2025-03-16T23:29:58.840Z TRACE lightningd: Plugin cln-xpay returned from rpc_command hook call
lightningd-1 2025-03-16T23:29:58.854Z TRACE lightningd: Calling rpc_command hook of plugin cln-xpay
lightningd-1 2025-03-16T23:29:58.865Z DEBUG gossipd: REPLY WIRE_GOSSIPD_NEW_BLOCKHEIGHT_REPLY with 0 fds
lightningd-1 2025-03-16T23:29:58.901Z **BROKEN** lightningd: Error executing statement: db/exec.c:108: UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?: attempt to write a readonly database
lightningd-1 2025-03-16T23:29:58.916Z **BROKEN** lightningd: Error executing statement: db/exec.c:108: UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?: attempt to write a readonly database
lightningd-1 2025-03-16T23:29:58.941Z **BROKEN** lightningd: FATAL SIGNAL 6 (version f91eb11-modded)
{'github_repository': 'ElementsProject/lightning', 'github_sha': 'f91eb118388dc1455c67d16079168fd0267ba248', 'github_ref': 'refs/pull/8112/merge', 'github_ref_name': 'HEAD', 'github_run_id': 13888173501, 'github_head_ref': 'flake-memleak', 'github_run_number': 12573, 'github_base_ref': 'master', 'github_run_attempt': '1', 'testname': 'test_setconfig_access', 'start_time': 1742167762, 'end_time': 1742167800, 'outcome': 'fail'}
----------------------------- Captured stderr call -----------------------------
Error executing statement: db/exec.c:108: UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?: attempt to write a readonly database
lightningd: FATAL SIGNAL 6 (version f91eb11-modded)
Log dumped in /tmp/lightning-crash.log.20250316232958
Lost connection to the RPC socket.Lost connection to the RPC socket.
=========================== short test summary info ============================
FAILED tests/test_misc.py::test_setconfig_access - AssertionError: Regex pattern did not match.
Regex: 'Cannot write to config file /tmp/ltests-22a5dz1j/test_setconfig_access_1/lightning-1/regtest/config'
Input: "RPC call failed: method: check, payload: {'command_to_check': 'setconfig', 'config': 'min-capacity-sat', 'val': 1000000}, error: Connection to RPC server lost."
ERROR tests/test_misc.py::test_setconfig_access - ValueError:
Node errors:
- lightningd-1: had BROKEN messages
- lightningd-1: Node exited with return code -6
```
So we move the db file for sqlite.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Modified by Rusty:
- Simplify (we only need to suppress l1's txs, since it opens)
- Use synchronize_blockheight instead of log messages to ensure l2 has processed the block
- Use listpeerchannels instead of log messages for balance (should be more robust against changes)
- Open-code assertions for better debugging if they're wrong.
Unfortunately a spec typo means the data fields are missing (PR pending),
so we still patch those in.
The message "your_peer_storage" got renamed to "peer_storage_retrieval",
and the option "want_peer_backup_storage" was removed.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: `experimental-peer-storage` now only advertizes feature 43, not 41.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Removed: RPC `listchannels` no longer includes private local channels (deprecated v23.08, disabled by default in v24.11).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Removed: plugins which didn't accept string JSON RPC fields (deprecated v23.08, disabled by default in v24.11).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Removed: allowing 0/1 instead of false/true for plugin options (deprecated v23.08, disabled by default in v24.11).
We now have to explicitly enable various deprecated commando commands, and now
when deprecations are disabled, we honour missing MPP option in bolt12 invoices.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
When we update the CLN_NEXT_VERSION, these will only be available with --i-promise-to-fix-broken-api-user.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
In d18f564324 "pytest: stop using
deprecated commando_rune commands." we stopped using deprecated commands in these tests,
but we didn't remove the 'allow-deprecated-apis' flag.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Really, any peer without a live channel is a bad prospect.
This requires us to wire the "enabled" flag through listincoming:
fortunately that's an internal, undocumented interface, so we don't
have a schema change.
Changelog-Fixed: Offline peers no longer selected for blinded paths..
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Fixes: https://github.com/ElementsProject/lightning/issues/8127
In 6e4ff6a7d2 ("offers: add a blinded path
if we have no advertized address") we were overzealous, and set blinded
paths not just for offers and invoicerequests, but for invoices themselves.
This has revealed various interop issues (which is great, but not good
for our users!) so we should disable that. It also reduces the reliability
of payments in general.
Changelog-None: fixes previously overzealous addition
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Use larger CLTVs and we see the failure from l3, complaining the CLTV is outside
the amount in the payment_constraint field, like:
```
Failing HTLC because of an invalid payload (TLV 10 pos 104): cltv_expiry 609 > payment_constraint 376
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
The old blindedpay fields would have an entry per hop, but that was changed
to a single per-path entry. The devtools hadn't caught up.
Similarly, it didn't like descriptionless offer fields in invreqs and invoices.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
If the nSequence in the tx it produces is not at least the value we
test in the script, the tx will always fail:
```
error code: -26\nerror message:\nmandatory-script-verify-flag-failed (Locktime requirement not satisfied)
```
If we have a lease, the nSequence is max(lease-time-remaining,
to-self-delay), so have onchaind tell lightningd the correct nSequence.
Fixes: https://github.com/ElementsProject/lightning/issues/7460
Reported-by: https://github.com/pabpas
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: Correctly collect our own (delayed) funds if we have a unilateral close when we are still offering a lease.
What we expect to happen:
1. l3, which unilaterally closed, waits 4032 blocks (minus those mined) before
trying to send get its "to_local" funds back.
2. This should then succeed.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
There are other ways we can disable it, of course (e.g full path name)
but this is the most obvious.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>