Commit Graph

3890 Commits

Author SHA1 Message Date
Rusty Russell
e36564f6dc pytest: make test_connect_ratelimit more robust
We were sending SIGSTOP to the lightningds, but that doesn't always
mean the connectd would stop it seems:

```
lightningd-1 2026-01-27T04:49:16.979Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: Initializing important peer with 1 addresses
lightningd-1 2026-01-27T04:49:16.979Z DEBUG   connectd: Got 10 bad cupdates, ignoring them (expected on mainnet)
lightningd-1 2026-01-27T04:49:16.979Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: Connected out, starting crypto
lightningd-1 2026-01-27T04:49:16.980Z DEBUG   038194b5f32bdf0aa59812c86c4ef7ad2f294104fa027d1ace9b469bb6f88cf37b-hsmd: Got WIRE_HSMD_ECDH_REQ
lightningd-1 2026-01-27T04:49:16.981Z DEBUG   hsmd: Client: Received message 1 from client
lightningd-1 2026-01-27T04:49:16.985Z TRACE   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-gossipd: handle_recv_gossip: WIRE_CHANNEL_ANNOUNCEMENT
lightningd-1 2026-01-27T04:49:16.985Z TRACE   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-gossipd: handle_recv_gossip: WIRE_CHANNEL_UPDATE
lightningd-1 2026-01-27T04:49:16.985Z TRACE   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-gossipd: handle_recv_gossip: WIRE_CHANNEL_UPDATE
lightningd-1 2026-01-27T04:49:16.985Z TRACE   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-gossipd: handle_recv_gossip: WIRE_NODE_ANNOUNCEMENT
lightningd-1 2026-01-27T04:49:16.985Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: Connect OUT
lightningd-1 2026-01-27T04:49:16.986Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: peer_out WIRE_INIT
lightningd-1 2026-01-27T04:49:16.986Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: peer_in WIRE_INIT
lightningd-1 2026-01-27T04:49:16.986Z TRACE   lightningd: Calling peer_connected hook of plugin chanbackup
lightningd-1 2026-01-27T04:49:16.986Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: Handed peer, entering loop
lightningd-1 2026-01-27T04:49:16.986Z DEBUG   03cecbfdc68544cc596223b68ce0710c9e5d2c9cb317ee07822d95079acc703d31-connectd: Initializing important peer with 1 addresses
lightningd-1 2026-01-27T04:49:16.986Z DEBUG   033845802d25b4e074ccfd7cd8b339a41dc75bf9978a034800444b51d42b07799a-connectd: Initializing important peer with 1 addresses
lightningd-1 2026-01-27T04:49:16.987Z DEBUG   033845802d25b4e074ccfd7cd8b339a41dc75bf9978a034800444b51d42b07799a-connectd: Too many connections, waiting...
lightningd-1 2026-01-27T04:49:16.987Z DEBUG   02186115cb7e93e2cb4d9d9fe7a9cf5ff7a5784bfdda4f164ff041655e4bcd4fd0-connectd: Initializing important peer with 1 addresses
lightningd-1 2026-01-27T04:49:16.987Z DEBUG   02186115cb7e93e2cb4d9d9fe7a9cf5ff7a5784bfdda4f164ff041655e4bcd4fd0-connectd: Too many connections, waiting...
lightningd-1 2026-01-27T04:49:16.987Z DEBUG   02287bfac8b99b35477ebe9334eede1e32b189e24644eb701c079614712331cec0-connectd: Initializing important peer with 1 addresses
lightningd-1 2026-01-27T04:49:16.987Z DEBUG   02287bfac8b99b35477ebe9334eede1e32b189e24644eb701c079614712331cec0-connectd: Too many connections, waiting...
lightningd-1 2026-01-27T04:49:16.987Z DEBUG   03cecbfdc68544cc596223b68ce0710c9e5d2c9cb317ee07822d95079acc703d31-connectd: Connected out, starting crypto
lightningd-1 2026-01-27T04:49:16.989Z DEBUG   038194b5f32bdf0aa59812c86c4ef7ad2f294104fa027d1ace9b469bb6f88cf37b-hsmd: Got WIRE_HSMD_ECDH_REQ
lightningd-1 2026-01-27T04:49:16.989Z DEBUG   hsmd: Client: Received message 1 from client
lightningd-1 2026-01-27T04:49:16.990Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: peer_in WIRE_GOSSIP_TIMESTAMP_FILTER
lightningd-1 2026-01-27T04:49:16.991Z DEBUG   03cecbfdc68544cc596223b68ce0710c9e5d2c9cb317ee07822d95079acc703d31-connectd: Connect OUT
lightningd-1 2026-01-27T04:49:16.991Z DEBUG   03cecbfdc68544cc596223b68ce0710c9e5d2c9cb317ee07822d95079acc703d31-connectd: peer_out WIRE_INIT
lightningd-1 2026-01-27T04:49:16.991Z DEBUG   0258f3ff3e0853ccc09f6fe89823056d7c0c55c95fab97674df5e1ad97a72f6265-connectd: peer_out WIRE_PEER_STORAGE
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-03 16:12:04 +10:30
Rusty Russell
cf3583ff83 pytest: mark renepay's self-pay test flaky
Not sure this is worth getting to the bottom of, if we're going for xpay?

```
2026-01-20T05:25:55.4375717Z lightningd-1 2026-01-20T05:22:41.062Z DEBUG   plugin-cln-renepay: sendpay_failure notification: {"sendpay_failure":{"code":202,"message":"Malformed error reply","data":{"created_index":2,"id":2,"payment_hash":"8447592dc3786c3181746bd7bf17fe9e84d3de3dfff847f9f2b8c1a65c2d3ff6","groupid":1,"partid":1,"destination":"038194b5f32bdf0aa59812c86c4ef7ad2f294104fa027d1ace9b469bb6f88cf37b","amount_msat":10000,"amount_sent_msat":10000,"created_at":1768886560,"status":"pending","bolt11":"lnbcrt100n1p5k7yfqsp5g072rrl6jn7wu8nlxk279zpkacz34hr22n089j4elguccfxmg0gqpp5s3r4jtwr0pkrrqt5d0tm79l7n6zd8h3alluy070jhrq6vhpd8lmqdqgw3jhxapjxqyjw5qcqp99qxpqysgq6dd74sj0vpyjy9he8pep73tt8pljhv6mc74y28rr8995yjyahgh9kc2jqwqz62h6u6jpqz0u9x6gcahdw3pe2x8r5eyppp53mlpru8sp4p4nf6","onionreply":"c5a02ce5372635959d87818f723767efe3137bbc40568fb04e1f2eedee0a6149000e400f00000000000027100000006c00f20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}}
2026-01-20T05:25:55.4386158Z lightningd-1 2026-01-20T05:22:41.067Z **BROKEN** plugin-cln-renepay: Unable to parse sendpay_failure: {"code":202,"message":"Malformed error reply","data":{"created_index":2,"id":2,"payment_hash":"8447592dc3786c3181746bd7bf17fe9e84d3de3dfff847f9f2b8c1a65c2d3ff6","groupid":1,"partid":1,"destination":"038194b5f32bdf0aa59812c86c4ef7ad2f294104fa027d1ace9b469bb6f88cf37b","amount_msat":10000,"amount_sent_msat":10000,"created_at":1768886560,"status":"pending","bolt11":"lnbcrt100n1p5k7yfqsp5g072rrl6jn7wu8nlxk279zpkacz34hr22n089j4elguccfxmg0gqpp5s3r4jtwr0pkrrqt5d0tm79l7n6zd8h3alluy070jhrq6vhpd8lmqdqgw3jhxapjxqyjw5qcqp99qxpqysgq6dd74sj0vpyjy9he8pep73tt8pljhv6mc74y28rr8995yjyahgh9kc2jqwqz62h6u6jpqz0u9x6gcahdw3pe2x8r5eyppp53mlpru8sp4p4nf6","onionreply":"c5a02ce5372635959d87818f723767efe3137bbc40568fb04e1f2eedee0a6149000e400f00000000000027100000006c00f20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}
```

```
2026-01-20T05:25:55.4465729Z         with pytest.raises(RpcError, match=r"Unknown invoice") as excinfo:
2026-01-20T05:25:55.4466111Z >           l1.rpc.call("renepay", {"invstring": inv2})
2026-01-20T05:25:55.4466310Z 
2026-01-20T05:25:55.4466402Z tests/test_renepay.py:423: 
...
2026-01-20T05:25:55.4489732Z         elif "error" in resp:
2026-01-20T05:25:55.4490005Z >           raise RpcError(method, payload, resp['error'])
2026-01-20T05:25:55.4492135Z E           pyln.client.lightning.RpcError: RPC call failed: method: renepay, payload: {'invstring': 'lnbcrt100n1p5k7yfqsp5g072rrl6jn7wu8nlxk279zpkacz34hr22n089j4elguccfxmg0gqpp5s3r4jtwr0pkrrqt5d0tm79l7n6zd8h3alluy070jhrq6vhpd8lmqdqgw3jhxapjxqyjw5qcqp99qxpqysgq6dd74sj0vpyjy9he8pep73tt8pljhv6mc74y28rr8995yjyahgh9kc2jqwqz62h6u6jpqz0u9x6gcahdw3pe2x8r5eyppp53mlpru8sp4p4nf6'}, error: {'code': -4, 'message': 'Plugin terminated before replying to RPC call.'}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-03 16:12:04 +10:30
Rusty Russell
f799c4c556 pytest: fix flake in test_sql.
If l2 hasn't seen l1's node_announcement yet:

```
        # Correctly handles missing object.
>       assert l2.rpc.sql("SELECT option_will_fund_lease_fee_base_msat,"
                          " option_will_fund_lease_fee_basis,"
                          " option_will_fund_funding_weight,"
                          " option_will_fund_channel_fee_max_base_msat,"
                          " option_will_fund_channel_fee_max_proportional_thousandths,"
                          " option_will_fund_compact_lease"
                          " FROM nodes WHERE HEX(nodeid) = '{}';".format(l1.info['id'].upper())) == {'rows': [[None] * 6]}
E       AssertionError: assert {'rows': []} == {'rows': [[None, None, None, None, None, None]]}
E         
E         Differing items:
E         {'rows': []} != {'rows': [[None, None, None, None, None, None]]}
E         
E         Full diff:
E           {
E         -     'rows': [
E         +     'rows': [],
E         ?              ++
E         -         [
E         -             None,
E         -             None,
E         -             None,
E         -             None,
E         -             None,
E         -             None,
E         -         ],
E         -     ],
E           }

tests/test_plugin.py:4131: AssertionError
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-03 16:12:04 +10:30
Rusty Russell
5c31d33786 common: remove legacy onion translation.
This was added in 24.05, but LND since 0.18.3 no longer ever creates
such onions, and even that version (September 2024) is now a long way
behind.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Removed: Protocol: we no longer support legacy onions (never sent by LND >= 0.18.3, which was the last)
2026-02-03 15:35:36 +10:30
Rusty Russell
6a937307b1 decode: don't treat every failure as a rune.
If we can't decode something, and it decodes as a rune (and all bech32
strings do!), then we would usually just complain it was a malformed
rune.  Be a big more useful, when the parameter looks like somthing else.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: JSON-RPC: `decode` is now more informative with malformed strings (won't claim everything is a malformed rune!).
2026-02-03 13:05:23 +10:30
Rusty Russell
5053e2e3f6 common: enforce currency-requires-amount check.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-03 13:05:23 +10:30
Rusty Russell
1de4e1dc28 pytest: test for amountless offer with currency.
Should fail: see https://github.com/lightning/bolts/pull/1279

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-03 13:05:23 +10:30
Tatiana Moroz
0173610527 Fix Reckless search command not finding partial matches
The Reckless search command was only returning a result if you
searched a perfect match, which is not too helpful.  This updates the
command so that partial search matches return a result.

Before:
reckless search bolt
Search exhausted all sources
reckless search bol
Search exhausted all sources
reckless search bolt12-pris
Search exhausted all sources

After:
reckless search bolt
Plugins matching 'bolt':
  bolt12-prism (https://github.com/lightningd/plugins)
reckless search bol
Plugins matching 'bol':
  bolt12-prism (https://github.com/lightningd/plugins)
reckless search bolt12-pris
Plugins matching 'bolt12-pris':
  bolt12-prism (https://github.com/lightningd/plugins)

Changelog-Fixed: reckless search now returns partial matches instead of requiring exact plugin names.
2026-02-02 13:01:00 -06:00
Christian Decker
ff34e485bc feat: Enhance JUnit XML reporting with environment variables and add import to conftest.py
Changelog-None
2026-02-02 11:41:09 +01:00
21M4TW
d76e4e7149 lightningd: don't allow enableoffer on single-use offer.
Changelog-Fixed: enableoffer: Adding an error when trying to activate an used single use offer (don't crash!)
2026-02-02 10:31:02 +10:30
Rusty Russell
e2d17cea0c pytest: test for crash when enableoffer called on a used single-use offer.
Assertion happens here:

	newstatus = offer_status_in_db(s | OFFER_STATUS_ACTIVE_F);

Since OFFER_STATUS_SINGLE_F|OFFER_STATUS_USED_F|OFFER_STATUS_ACTIVE_F
is not a valid combination:

```
lightningd-3 2026-01-28T04:45:21.184Z **BROKEN** lightningd: offer_status_in_db: 7 is invalid
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: FATAL SIGNAL 6 (version v25.12-92-g7fff32d-modded)
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: common/daemon.c:83 (crashdump) 0x5a883759dbb7
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 ((null)) 0x79a2b0c4532f
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ./nptl/pthread_kill.c:44 (__pthread_kill_implementation) 0x79a2b0c9eb2c
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ./nptl/pthread_kill.c:78 (__pthread_kill_internal) 0x79a2b0c9eb2c
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ./nptl/pthread_kill.c:89 (__GI___pthread_kill) 0x79a2b0c9eb2c
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ../sysdeps/posix/raise.c:26 (__GI_raise) 0x79a2b0c4527d
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ./stdlib/abort.c:79 (__GI_abort) 0x79a2b0c288fe
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/log.c:1054 (fatal_vfmt) 0x5a8837509557
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/log.c:1064 (fatal) 0x5a88375095fe
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ./wallet/wallet.h:1451 (offer_status_in_db) 0x5a88375491dc
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: wallet/wallet.c:6160 (offer_status_in_db) 0x5a8837555388
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: wallet/wallet.c:6162 (wallet_offer_enable) 0x5a8837555388
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/offer.c:288 (json_enableoffer) 0x5a8837540939
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/jsonrpc.c:769 (command_exec) 0x5a8837503198
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/jsonrpc.c:910 (rpc_command_hook_final) 0x5a8837503198
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/jsonrpc.c:884 (rpc_command_hook_final) 0x5a8837503198
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/plugin_hook.c:243 (hook_done) 0x5a8837535383
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/plugin_hook.c:343 (plugin_hook_call_next) 0x5a8837535383
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/jsonrpc.c:998 (plugin_hook_call_rpc_command) 0x5a8837503c4f
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/jsonrpc.c:1123 (parse_request) 0x5a8837503c4f
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/jsonrpc.c:1217 (read_json) 0x5a8837503c4f
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:60 (next_plan) 0x5a88375eca38
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:422 (do_plan) 0x5a88375eca38
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:439 (io_ready) 0x5a88375eca38
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ccan/ccan/io/poll.c:470 (io_loop) 0x5a88375eead5
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/io_loop_with_timers.c:22 (io_loop_with_timers) 0x5a8837501f8e
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: lightningd/lightningd.c:1492 (main) 0x5a88374d3c27
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ../sysdeps/nptl/libc_start_call_main.h:58 (__libc_start_call_main) 0x79a2b0c2a1c9
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: ../csu/libc-start.c:360 (__libc_start_main_impl) 0x79a2b0c2a28a
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: (null):0 ((null)) 0x5a88374d5aa4
lightningd-3 2026-01-28T04:45:21.260Z **BROKEN** lightningd: backtrace: (null):0 ((null)) 0xffffffffffffffff
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-02 10:31:02 +10:30
Lagrang3
f1bf66c91f askrene: fixed a timeout corner case
Changelog-Fixed: askrene: fixed a class of corner cases that cause askrene main loop to timeout instead of quickly failing, thus wasting runtime.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2026-02-02 10:23:27 +10:30
Lagrang3
597da1fef9 askrene: add test that triggers infinite loop
Changelog-None

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2026-02-02 10:23:27 +10:30
Lagrang3
bb3be7e8f8 askrene: remove unnecessary print in test
Changelog-None

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2026-02-02 10:23:27 +10:30
Chandra Pratap
461ca68688 fuzz-tests: Add coverage increasing inputs to seed corpora
Improvements in the fuzz-testing scheme of
`fuzz-bolt12-offer-decode` led to the discovery of test inputs
that result in greater in code coverage.

Add these inputs to the test's seed corpus.
2026-01-30 15:23:11 +10:30
Chandra Pratap
557a744bb7 fuzz-tests: Make fuzz-bolt12-offer-decode roundrip
Changelog-None: Currently, the `BOLT #12` offer parsing test only
tests the offer decode function. Add a test for the encoding
function as well by making the test roundtrip.
2026-01-30 15:23:11 +10:30
Lagrang3
3822a67030 askrene: add auto.include_fees layer
Changelog-Added: askrene: add a new layer auto.include_fees thhat makes fees be deducted from the payment amount making in effect the receiver pay for routing fees.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2026-01-29 15:20:25 +10:30
Rusty Russell
c7d313ea00 pytest: also make sure askrene doesn't suffer when reloading many layers on startup.
We used non-persistent layers before, but what if we save to the datastore and restore?

This takes it from 29 to 45 seconds.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 13:59:36 +10:30
Rusty Russell
a3946663ec askrene: speed up when using large number of layers.
Simple bench.

Before:
   Creating 20,000 layers:  20 seconds
   Creating 50,000 layers:  107 seconds

After:
   Creating 20,000 layers:  7 seconds
   Creating 50,000 layers:  15 seconds
   Creating 100,000 layers: 29 seconds

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 13:59:36 +10:30
Rusty Russell
ff60983319 pytest: add askrene layer creation bench.
This means it has to do a lookup and an insert.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 13:59:36 +10:30
Sangbida Chaudhuri
1279a58910 pytest: changed old_hsmsecret to default to false.
This changes various tests in minor ways:

1. The "l2" secret key in tests/plugins/channeld_fakenet.c is updated.
2. The decompressed gossip data node id needs changing.
3. The coinmoves order changes in bookkeeper for anchors.
4. Various harcoded gossip constants change.
5. Some hardcoded makesecret results change.
6. zeroconf tests which hardcoded node ids change.
7. Arbitrary rune strings change.
8. A log message which uses node ids changes.
2026-01-27 09:32:49 +10:30
Rusty Russell
12bc5b04e2 pytest: use hsmtool's getsecret instead of deprecated getcodexsecret, parameterize test_recover_command.
This matters for mnemonic nodes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 09:32:49 +10:30
Rusty Russell
b2b03e6e46 pytest: parameterize test_showrunes.
Another one we want to make sure stays unchanged.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 09:32:49 +10:30
Sangbida Chaudhuri
129b207742 pytest: test upfront_shutdown_script with new-style hsm_secret too. 2026-01-27 09:32:49 +10:30
Rusty Russell
dae9140a8b pytest: parameterize test_payerkey and test_exposesecret.
These are explicitly written to check that the values don't accidentally change,
which applies to both old and new styles.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 09:32:49 +10:30
Sangbida Chaudhuri
c653955de1 tests: update test so use both node ids
This test has been split into two to assert on both the old and the new hsm_secret
2026-01-27 09:32:49 +10:30
Sangbida Chaudhuri
9d331f5455 test: mark bookkeeper test to use old hsm secret
bookkeeper's fee tracking depends on deterministic channel structure, which depends on node ID ordering. I'm marking this with the old_hsmsecret option for now.
2026-01-27 09:32:49 +10:30
Sangbida Chaudhuri
c076a100c2 test: use old hsmsecret format for hardcoded onion message 2026-01-27 09:32:49 +10:30
Rusty Russell
cb51b7ea91 pytest: test names for new nodes. 2026-01-27 09:32:49 +10:30
Rusty Russell
c7973b8ae0 pytest: make sure to use old_hsmsecret on downgrade tests.
We only support downgrade if you upgraded, so your hsm_secret will be old.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 09:32:49 +10:30
Sangbida Chaudhuri
81d1d4a367 pytest: use old hsm secret whenever a canned database files is used
Anything using a canned db depends on the node ids being generated from the old hsm seed.
2026-01-27 09:32:49 +10:30
Sangbida Chaudhuri
6a9bdb8087 pytest: determine scid direction dynamically
Since we have changed our hsm_secret seed the node ids have all change hence the asseertions on the scids break. This changes it so that the direction is determined when the test executes.
2026-01-27 09:32:49 +10:30
Rusty Russell
4d8f923a9a logging: switch to a simple ringbuffer.
We keep a history of logs internally, so we can drop them to disk on a
crash.  This "black box recorder" was some of the first code I wrote
for CLN, but I can't remember the last time we use a crash log to
diagnose a problem.

We attempt to prune it to keep it under 10MB, but the complexity
and cost is rarely worth it: simplify it to use a ringbuffer.

Changelog-Changed: lightningd: logging is now more efficient internally (no more pruning, simple ringbuffer).

```
     139993 DEBUG   lightningd: fixup_scan: block 786151 with 1203 txs
===>  55388 DEBUG   plugin-bcli: Log pruned 1001 entries (mem 10508118 -> 10298662)
      33000 DEBUG   gossipd: Unreasonable timestamp in 0102000a38ec41f9137a5a560dac6effbde059c12cb727344821cbdd4ef46964a4791a0f67cd997499a6062fc8b4284bf1b47a91541fd0e65129505f02e4d08542b16fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000000d9d56000ba40001690fe262010100900000000000000001000003e8000001f30000000000989680
      23515 DEBUG   hsmd: Client: Received message 14 from client
      22269 DEBUG   024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605-hsmd: Got WIRE_HSMD_ECDH_REQ
      14409 DEBUG   gossipd: Enqueueing update for announce 0102002f7e4b4deb19947c67292e70cb22f7fac837fa9ee6269393f3c513d0431d52672e7387625856c19299cfd584e1a3f39e0f98df13c99090df9f4d5cca8446776fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000000e216b0008050001692e1c390101009000000000000003e800000000000013880000004526945a00
      12534 DEBUG   gossipd: Previously-rejected announce for 514127x248x1
      10761 DEBUG   02e01367e1d7818a7e9a0e8a52badd5c32615e07568dbe0497b6a47f9bef89d6af-channeld-chan#70770: Got it!
      10761 DEBUG   02e01367e1d7818a7e9a0e8a52badd5c32615e07568dbe0497b6a47f9bef89d6af-channeld-chan#70770: ... , awaiting 1120
      10761 DEBUG   02e01367e1d7818a7e9a0e8a52badd5c32615e07568dbe0497b6a47f9bef89d6af-channeld-chan#70770: Sending master 1020
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-27 09:31:02 +10:30
Rusty Russell
592f8586f4 lightningd: remove decodepay.
Changelog-Removed: JSON-RPC: `decodepay` (use `decode`), deprecated v24.11.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-20 19:32:42 +10:30
Rusty Russell
9881e04636 lightningd: remove the "listpeers.features.option_anchors_zero_fee_htlc_tx" option.
Everyone should be using the new name.

Changelog-Removed: JSON-RPC: `listpeers` `features` array string "option_anchors_zero_fee_htlc_tx": use "option_anchors" (spec renamed it). Deprecated in 24.08.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-20 19:32:42 +10:30
Rusty Russell
ee0175b85f Makefile: update next and prev versions now we've released.
This means:
1. downgrade changes (we no longer fail due to node biases).
2. various deprecations no longer are

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-20 19:32:42 +10:30
daywalker90
d03cf820a8 clnrest: add clnrest-register-path method for dynamic paths
Changelog-Added: clnrest: add clnrest-register-path rpc method to register dynamic paths
2026-01-19 12:55:57 +10:30
Rusty Russell
d2123a94a5 lightning-hsmtool: fix dumponchaindescriptors for mnemonic hsm_secrets.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: `lightning-hsmtool`: handle mnemonic hsm_secret files (nodes created >= v25.12).
2026-01-14 17:18:56 +10:30
Rusty Russell
b0f8077e32 pytest: fix flake in test_gossip_query_channel_range
If l4 sends a WIRE_QUERY_SHORT_CHANNEL_IDS at the wrong time, we will
get that and be upset the response is wrong:

```
2026-01-13T14:45:55.9059786Z E       AssertionError: assert ['010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00000000000f42400100110000006800000100000000690000010000', '010506226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f001100000068000001000000006900000100000103000402'] in (['010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00000000000f42400100110000006800000100000000690000010000'], ['010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00000000000f42400100110000006900000100000000680000010000'])
2026-01-13T14:45:55.9063357Z 
2026-01-13T14:45:55.9063527Z tests/test_gossip.py:762: AssertionError
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-14 15:41:45 +10:30
Rusty Russell
84afe57919 pytest: disable autoreconnect on test_sql to avoid reconnect race.
Because l1 and l3 allow localhost as a broadcastable address, they can
try to reconnect.  Disable reconnections, so we don't race:

```
>       l2.rpc.connect(l3.info['id'], 'localhost', l3.port)

tests/test_plugin.py:4146: 
...	    
        elif "error" in resp:
>           raise RpcError(method, payload, resp['error'])
E           pyln.client.lightning.RpcError: RPC call failed: method: connect, payload: {'id': '035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d', 'host': 'localhost', 'port': 45035}, error: {'code': 402, 'message': 'disconnected during connection'}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-14 15:41:45 +10:30
Rusty Russell
3be25d48d3 pytest: don't rely on sleep to ensure wait commands have been submitted.
Seems like sleep(1) isn't always enough.  Give in and put a log
message there, and use that:

```
	waitfut = executor.submit(l2.rpc.wait, subsystem='forwards', indexname='deleted', nextvalue=1)
        time.sleep(1)
    
        l2.rpc.delforward(scid12, 1, 'failed')
    
        waitres = waitfut.result(TIMEOUT)
>       assert waitres == {'subsystem': 'forwards',
                           'deleted': 1,
                           'forwards': {'in_channel': scid12,
                                        'in_htlc_id': 1,
                                        'status': 'failed'}}
E       AssertionError: assert {'subsystem': 'forwards', 'deleted': 1} == {'subsystem': 'forwards', 'deleted': 1, 'forwards': {'in_channel': '103x2x0', 'in_htlc_id': 1, 'status': 'failed'}}
E         
E         Common items:
E         {'deleted': 1, 'subsystem': 'forwards'}
E         Right contains 1 more item:
E         {'forwards': {'in_channel': '103x2x0', 'in_htlc_id': 1, 'status': 'failed'}}
E         
E         Full diff:
E           {
E               'deleted': 1,
E         -     'forwards': {
E         -         'in_channel': '103x2x0',
E         -         'in_htlc_id': 1,
E         -         'status': 'failed',
E         -     },
E               'subsystem': 'forwards',
E           }

tests/test_misc.py:3599: AssertionError
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-14 15:41:45 +10:30
Rusty Russell
c10c54ff23 pytest: don't record IO when we kill nodes
```
ERROR tests/test_connection.py::test_channel_persistence - json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```

Similarly:

```
ERROR tests/test_opening.py::test_sendpsbt_crash - json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-14 15:41:45 +10:30
Rusty Russell
8d807be6bf pytest: fix reconnect flake in test_route_by_old_scid
We restart l2, then try to connect to l1.  But l1 will be trying to
reconnect (and it can, since it was initially given l2's address), so
it can race us and we end up disconnecting because of simultaneous
connect:

```
2026-01-13T04:06:10.7490260Z >       l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
2026-01-13T04:06:10.7490667Z 
2026-01-13T04:06:10.7490828Z tests/test_splicing.py:554: 
...
2026-01-13T04:06:10.7525780Z >           raise RpcError(method, payload, resp['error'])
2026-01-13T04:06:10.7527464Z E           pyln.client.lightning.RpcError: RPC call failed: method: connect, payload: {'id': '0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518', 'host': 'localhost', 'port': 46813}, error: {'code': 402, 'message': 'disconnected during connection'}
2026-01-13T04:06:10.7528832Z
...
2026-01-13T04:06:10.9411680Z lightningd-2 2026-01-13T03:59:59.463Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: Connect OUT
2026-01-13T04:06:10.9412178Z lightningd-2 2026-01-13T03:59:59.463Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: peer_out WIRE_INIT
2026-01-13T04:06:10.9412551Z lightningd-2 2026-01-13T03:59:59.463Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: Connect IN
2026-01-13T04:06:10.9412947Z lightningd-2 2026-01-13T03:59:59.464Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: peer_out WIRE_INIT
2026-01-13T04:06:10.9413342Z lightningd-2 2026-01-13T03:59:59.464Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: peer_in WIRE_INIT
2026-01-13T04:06:10.9413624Z lightningd-2 2026-01-13T03:59:59.487Z TRACE   lightningd: Calling peer_connected hook of plugin chanbackup
2026-01-13T04:06:10.9414057Z lightningd-2 2026-01-13T03:59:59.534Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: Handed peer, entering loop
2026-01-13T04:06:10.9414451Z lightningd-2 2026-01-13T03:59:59.534Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: peer_in WIRE_INIT
2026-01-13T04:06:10.9414851Z lightningd-2 2026-01-13T03:59:59.574Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-lightningd: peer reconnected
2026-01-13T04:06:10.9415250Z lightningd-2 2026-01-13T03:59:59.609Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-lightningd: peer_disconnected
2026-01-13T04:06:10.9415527Z lightningd-2 2026-01-13T03:59:59.685Z TRACE   lightningd: Calling peer_connected hook of plugin chanbackup
2026-01-13T04:06:10.9415957Z lightningd-2 2026-01-13T03:59:59.687Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: Handed peer, entering loop
2026-01-13T04:06:10.9416364Z lightningd-2 2026-01-13T03:59:59.757Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-lightningd: peer_disconnected
2026-01-13T04:06:10.9417067Z lightningd-2 2026-01-13T03:59:59.830Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: Will try reconnect in 4 seconds
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-14 15:41:45 +10:30
Rusty Russell
c0c885492f pytest: another flake in test_important_plugin.
There's one more complaint we can see when plugins get upset:

```
lightningd-1 2026-01-12T06:10:49.317Z **BROKEN** plugin-cln-xpay: askrene-create-layer failed with {"code":-4, "message":"Plugin terminated before replying to RPC call."}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-14 15:41:45 +10:30
Rusty Russell
779a478437 lightningd: allow --recover / recover JSON RPC to take mnemonic.
In fact, you *must* use mnemonic to successfully recover a modern node!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: JSON-RPC: `recover` takes a 12-word mnemonic for nodes created by v25.12 or later.
2026-01-13 22:36:01 +10:30
Rusty Russell
f975bb37d4 lightning-hsmtool: support extracting the mnemonic from hsm_secret.
We cannot use the codex32 or raw hex for recovery of 25.12 nodes,
since they will then use the incorrect derivation for all paths, and
be unable to spend (or even find!) their funds.

So implement `getsecret` to replace `getcodexsecret`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: `lightning-hsmtool`: `getsecret` replaces `getcodexsecret` for modern nodes (gives mnemonic).
Changelog-Deprecated: `lightning-hsmtool`: `getcodexsecret`.  Use `getsecret`.
2026-01-13 22:36:01 +10:30
Lagrang3
118e474637 askrene: fix payment crash
Changelog-Fixed: askrene: fix a plugin crash triggered during single path payments when a channel fees doesn't fit u32.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2026-01-13 15:16:46 +10:30
Lagrang3
a0cc50cf8e askrene: regression test that triggers assertion
cln-askrene: plugins/askrene/mcf.c:474: combine_cost_function: Assertion `fcost != INFINITE' failed.
cln-askrene: FATAL SIGNAL 6 (version v25.12-131-gb15f386-modded)
0x55703f242fd1 send_backtrace
	common/daemon.c:38
0x55703f24305b crashdump
	common/daemon.c:83
0x7f548b421def ???
	./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0x7f548b47695c __pthread_kill_implementation
	./nptl/pthread_kill.c:44
0x7f548b421cc1 __GI_raise
	../sysdeps/posix/raise.c:26
0x7f548b40a4ab __GI_abort
	./stdlib/abort.c:73
0x7f548b40a41f __assert_fail_base
	./assert/assert.c:118
0x55703f234491 combine_cost_function
	plugins/askrene/mcf.c:474
0x55703f2358b6 single_path_flow
	plugins/askrene/mcf.c:1213
0x55703f235fa2 linear_routes
	plugins/askrene/mcf.c:1411
0x55703f236804 single_path_routes
	plugins/askrene/mcf.c:1656
0x55703f22edad do_getroutes
	plugins/askrene/askrene.c:689
0x55703f22f269 json_getroutes
	plugins/askrene/askrene.c:910
0x55703f2411a7 ld_command_handle
	plugins/libplugin.c:2155
0x55703f2413b1 ld_read_json
	plugins/libplugin.c:2231
0x55703f271a4d next_plan
	ccan/ccan/io/io.c:60
0x55703f271ed8 do_plan
	ccan/ccan/io/io.c:422
0x55703f271f91 io_ready
	ccan/ccan/io/io.c:439
0x55703f27391b io_loop
	ccan/ccan/io/poll.c:470
0x55703f2417fd plugin_main
	plugins/libplugin.c:2429
0x55703f22f753 main
	plugins/askrene/askrene.c:1452
0x7f548b40bca7 __libc_start_call_main
	../sysdeps/nptl/libc_start_call_main.h:58
0x7f548b40bd64 __libc_start_main_impl
	../csu/libc-start.c:360
0x55703f22baa0 ???
	_start+0x20:0
0xffffffffffffffff ???
	???:0

Changelog-None

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2026-01-13 15:16:46 +10:30
Rusty Russell
b15f386df6 pytest: fix bad gossip flake in test_buy_liquidity_ad_check_bookkeeping
If we don't wait for the channel announcement to be processed, we can
get bad gossip:

```
lightningd-2 2026-01-08T04:53:53.795Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-chan#2: Funding tx 2f41b1cc99dea016b7feddbeb1f31ae21b30f56d77ecb2ecb2b2f0faff4808fe depth 12 of 1
lightningd-2 2026-01-08T04:53:53.795Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-chan#2: Funding tx 2f41b1cc99dea016b7feddbeb1f31ae21b30f56d77ecb2ecb2b2f0faff4808fe confirmed, but peer in state ONCHAIN
lightningd-2 2026-01-08T04:53:53.802Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-onchaind-chan#2: Got new message WIRE_ONCHAIND_DEPTH
lightningd-2 2026-01-08T04:53:53.802Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-onchaind-chan#2: Sending 0 missing htlc messages
lightningd-2 2026-01-08T04:53:53.802Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-onchaind-chan#2: FUNDING_TRANSACTION/FUNDING_OUTPUT->MUTUAL_CLOSE depth 6
lightningd-2 2026-01-08T04:53:53.802Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-onchaind-chan#2: billboard: All outputs resolved: waiting 94 more blocks before forgetting channel
lightningd-2 2026-01-08T04:53:53.812Z DEBUG   gossipd: gossmap_manage: new block, adding 104x1x1 to pending...
lightningd-2 2026-01-08T04:53:53.812Z DEBUG   gossipd: REPLY WIRE_GOSSIPD_NEW_BLOCKHEIGHT_REPLY with 0 fds
lightningd-1 2026-01-08T04:53:53.819Z DEBUG   022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59-connectd: peer_in WIRE_WARNING
lightningd-1 2026-01-08T04:53:53.820Z DEBUG   022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59-connectd: Received WIRE_WARNING: WARNING: channel_announcement: no unspent txout 104x1x1
lightningd-2 2026-01-08T04:53:53.820Z TRACE   gossipd: channel_announcement: got reply for 104x1x1...
lightningd-2 2026-01-08T04:53:53.820Z TRACE   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-gossipd: Bad gossip order: channel_announcement: no unspent txout 104x1x1
lightningd-2 2026-01-08T04:53:53.820Z DEBUG   0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-connectd: peer_out WIRE_WARNING
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-08 22:33:19 +10:30
Rusty Russell
3d59af6f98 pytest: fix coinmoves flake, where routing credit/debit can appear in either order.
It's done as HTLCs finalize, but we can close the incoming HTLC as soon as we get the
preimage, so that entire thing could finish before the outgoing HTLC.

```
>       check_channel_moves(l1, expected_channel1)

tests/test_coinmoves.py:307: 
...
E         Full diff:
E           [
E               {
E                   'account_id': '58d371ab100e0ea847a11c9550add273ef8531bc12bb51b0e30c8f833506a772',
E                   'created_index': 1,
E                   'credit_msat': 0,
E                   'debit_msat': 1000000,
E                   'fees_msat': 0,
E                   'group_id': 1318196858430961660,
E                   'part_id': 1,
E                   'payment_hash': '8da829ab29715106a4e767facc0b58776ae5bfc11c4e9dcda3063013e1ef8ef0',
E                   'primary_tag': 'invoice',
E               },
E               {
E                   'account_id': '0b872506f67b363803cd85cf9ff6807ebc1dc8a4521aa191386b4c5366d490d7',
E                   'created_index': 2,
E                   'credit_msat': 100000,
E                   'debit_msat': 0,
E                   'fees_msat': 0,
E                   'primary_tag': 'pushed',
E               },
E               {
E         +         'account_id': '0b872506f67b363803cd85cf9ff6807ebc1dc8a4521aa191386b4c5366d490d7',
E         +         'created_index': 3,
E         +         'credit_msat': 10000100001,
E         +         'debit_msat': 0,
E         +         'fees_msat': 100001,
E         +         'payment_hash': '0ebfa5387de5fd12c15089833b0193fb6007e9f494ec24d479e327a96ac8e8c0',
E         +         'primary_tag': 'routed',
E         +     },
E         +     {
E                   'account_id': '58d371ab100e0ea847a11c9550add273ef8531bc12bb51b0e30c8f833506a772',
E         -         'created_index': 3,
E         ?                          ^
E         +         'created_index': 4,
E         ?                          ^
E                   'credit_msat': 0,
E                   'debit_msat': 10000000000,
E                   'fees_msat': 100001,
E                   'payment_hash': '0ebfa5387de5fd12c15089833b0193fb6007e9f494ec24d479e327a96ac8e8c0',
E                   'primary_tag': 'routed',
E               },
E         -     {
E         -         'account_id': '0b872506f67b363803cd85cf9ff6807ebc1dc8a4521aa191386b4c5366d490d7',
E         -         'created_index': 4,
E         -         'credit_msat': 10000100001,
E         -         'debit_msat': 0,
E         -         'fees_msat': 100001,
E         -         'payment_hash': '0ebfa5387de5fd12c15089833b0193fb6007e9f494ec24d479e327a96ac8e8c0',
E         -         'primary_tag': 'routed',
E         -     },
E           ]
```
2026-01-08 22:33:19 +10:30