Commit Graph

586 Commits

Author SHA1 Message Date
Rusty Russell
939aec3b61 pytest: make hold_timeout.py test plugin release on a prompt, not timeout.
Avoids guessing what the timeout should be, use a file trigger.  This
is more optimal, and should reduce a flake in test_sql under valgrind.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-02-09 14:48:15 +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
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
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
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
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
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
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
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
2333f024d3 pytest: work around pay flakiness.
pay sometimes ignores exclusions.  WONTFIX.

```
        with pytest.raises(RpcError, match=r'is not reachable directly and all routehints were unusable.'):
>           l1.rpc.pay(inv, exclude=[scid12])

tests/test_pay.py:5279: 
...
        elif "error" in resp:
>           raise RpcError(method, payload, resp['error'])
E           pyln.client.lightning.RpcError: RPC call failed: method: pay, payload: {'bolt11': 'lnbcrt1230n1p54mma3sp5x7uerjgyg7ws6fnzdwxc7pgpj6j25uhpqp5uvx3fk8dkcqm37m2spp5k02racjc9knux958u5rgtva24jfvxtr5w3t53pfeavn3thmyny0qdq8v3jhxccxqyjw5qcqp9rzjqgkjyd3q5dv6gllh77kygly9c3kfy0d9xwyjyxsq2nq3c83u5vw4jqqqvuqqqqgqqqqqqqqpqqqqqzsqqc9qxpqysgqcmv875mmzcjl8mwxxndy9an6p870ffpdxdtypmgf5gzsydnt2d68n4kjph0rcprye6tfz0ex0c5clgj3zwm8jgd5vs0fdv7hf7dqr8cqdrg3gf', 'exclude': ['103x2x0/1']}, error: {'code': 210, 'message': 'Ran out of routes to try after 6 attempts: see `paystatus`', 'attempts': [{'status': 'failed', 'failreason': 'No path found', 'partid': 0, 'amount_msat': 123000}, {'status': 'pending', 'failreason': 'No path found', 'partid': 1, 'amount_msat': 123000, 'parent_partid': 0}, {'status': 'failed', 'failreason': 'No path found', 'partid': 2, 'amount_msat': 57006, 'parent_partid': 1}, {'status': 'failed', 'failreason': 'No path found', 'partid': 4, 'amount_msat': 57006, 'parent_partid': 2}, {'status': 'failed', 'failreason': 'No path found', 'partid': 3, 'amount_msat': 65994, 'parent_partid': 1}, {'status': 'failed', 'failreason': 'No path found', 'partid': 5, 'amount_msat': 65994, 'parent_partid': 3}]}
```

The logs show that it doesn't exclude the routehint early: in successful runs we get "After filtering routehints we're left with 0 usable hints".  Perhaps this is something to do with the timing of our own notifications?

```
2026-01-07T05:51:10.7902502Z lightningd-1 2026-01-07T05:31:29.706Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Received getchaininfo blockcount=108, headercount=108
2026-01-07T05:51:10.7903334Z lightningd-1 2026-01-07T05:31:29.715Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: waitblockheight reports syncheight=108
2026-01-07T05:51:10.7904256Z lightningd-1 2026-01-07T05:31:29.734Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Updated a channel hint for 103x2x0/1: enabled true, estimated capacity 978718000msat
2026-01-07T05:51:10.7905355Z lightningd-1 2026-01-07T05:31:29.734Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Updated a channel hint for 7269357x11669990x33910/1: enabled false, estimated capacity UNKNOWN
2026-01-07T05:51:10.7906580Z lightningd-1 2026-01-07T05:31:29.735Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Updated a channel hint for 103x2x0/1: enabled false, estimated capacity UNKNOWN
2026-01-07T05:51:10.7907665Z lightningd-1 2026-01-07T05:31:29.735Z INFO    plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Payment fee constraint 615msat is below exemption threshold, allowing a maximum fee of 5000msat
2026-01-07T05:51:10.7908845Z lightningd-1 2026-01-07T05:31:29.752Z DEBUG   plugin-pay: Received a channel_hint {.scid = 103x2x0/1, .enabled = 1, .estimate = 978718000msat, .capacity = 1000000000msat }
2026-01-07T05:51:10.7909710Z lightningd-1 2026-01-07T05:31:29.754Z INFO    plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Filtering out 1 routehints
2026-01-07T05:51:10.7910544Z lightningd-1 2026-01-07T05:31:29.779Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Checking hint {.scid=103x2x0/1, .enabled=1, .estimate=978718000msat}
2026-01-07T05:51:10.7911470Z lightningd-1 2026-01-07T05:31:29.780Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: After filtering routehints we're left with 1 usable hints
2026-01-07T05:51:10.7912385Z lightningd-1 2026-01-07T05:31:29.780Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Checking hint {.scid=103x2x0/1, .enabled=1, .estimate=978718000msat}
2026-01-07T05:51:10.7913471Z lightningd-1 2026-01-07T05:31:29.780Z DEBUG   plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Using routehint 022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59 (103x1x0) cltv_delta=6
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-08 22:33:19 +10:30
Rusty Russell
25fb75e4be pytest: restore and fix disabled test test_excluded_adjacent_routehint.
1. It was flaky, probably because it didn't wait for the remote update_channel.
2. Rusty applied a fix in 5f664dac77, not clear if it worked.
3. Christian disabled it altogether in 23ce9a947d.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-08 22:33:19 +10:30
Rusty Russell
9ad505acec pytest: remove test_lockup_drain.
Since this was written, we now test if remote side would get into this situation and stop
it from happening, so the test doesn't work any more.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-01-08 22:33:19 +10:30
ShahanaFarooqui
1887ed4ae5 test: Add tests to confirm that description is added to RPCs 2025-12-19 15:28:46 -08:00
wqxoxo
bc3b9b4f11 pay: Enforce maxdelay for direct channel payments
When paying through a direct channel, direct_pay_override() creates a
route bypassing the normal routing path, which skips the CLTV budget
check in payment_getroute(). This allows payments to succeed even when
maxdelay is set below the required min_final_cltv_expiry.

Add a check in direct_pay_override() to verify the required CLTV
doesn't exceed cltv_budget before using the direct channel shortcut.
If it exceeds, skip the direct channel and let normal routing handle
the failure with a proper error message.

Fixes: #8609

Changelog-Fixed: pay: `maxdelay` parameter now enforced for direct channel payments
2025-12-19 12:41:17 +01:00
Wes Payne
89270024e8 keysend: enforce BOLT11 description length limit
The keysend plugin previously used `> 1023` as the cutoff for
description length when inserting an invoice. This was
inconsistent with invoice.c, which enforces the BOLT11 description
field limit defined in `common/bolt11.h`.

This patch switches to using `BOLT11_FIELD_BYTE_LIMIT` directly.
As a result, keysend no longer fails on descriptions between
641–1023 bytes, which previously caused unexpected failures.

A new regression test (`test_keysend_description_size_limit`)
exercises boundary cases just below, at, and above the limit.

Changelog-Fixed: Protocol: `keysend` with descriptions of length 640-1023 bytes fixed.
Signed-off-by: Wes Payne <noblepayne@noblepayne.com>
2025-11-13 10:57:49 +10:30
Peter Neuroth
21fb7600f3 lightningd: add invoice_amt to the htlc_accepted hook
This commit introduces a new field `invoice_msat` to the htlc_accepted
hook. If this field is specified it will replace the amount of the
invoice that belongs to the payment_hash of the HTLC on internal checks.

This is useful in scenarios where we actually expect a smaller amount
than initially specified in an invoice.

Changelog-Changed: Plugins: `htlc_accepted` hook can now override the
expected total amount of the invoice that belongs to the HTLC.

Signed-off-by: Peter Neuroth <pet.v.ne@gmail.com>
2025-11-10 15:05:27 +10:30
Rusty Russell
ac60568398 lightningd: fix case where injectpaymentonion failure results in listsendpays "pending".
If we failed after we register (e.g. channeld not available), we don't
mark it failed.  We shouldn't register until we've definitely created
the htlc.

Changelog-Fixed: `xpay` would sometimes leave payment parts status `pending` in failure cases (as seen in listpays or listsendpays).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Fixes: https://github.com/ElementsProject/lightning/issues/8629
2025-11-04 11:06:50 +10:30
Rusty Russell
350578d767 pytest: test that we correctly mark a payment part failed if we cannot queue it to the channeld for the peer.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-04 11:06:50 +10:30
Rusty Russell
5e53af7d3f plugins/offers: handle invoice_request with invreq_recurrence_cancel
In this case, we make an immediately-expiring invoice.  This correctly blocks
any successive requests for invoices, as per the spec requirement.

This means we have to handle invoice_requests without reply_path, amounts
or quantity *if* they specify invreq_recurrence_cancel.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-01 15:31:30 +09:30
Rusty Russell
b30e063432 plugins/fetchinvoice: allow use of expired offers *for recurrence*.
We added this to the recurrence spec: the offer expiration only applies to the
first request, not subsequent ones.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-01 15:31:30 +09:30
Rusty Russell
54444e4337 BOLT12: Update recurrence to latest spec draft.
Changes:
* Fields renumbered to their draft values + billion.
* offer_recurrence now comes in compulsory or optional (backwards compat) flavors.
* `proportional_amount` is now inside `offer_recurrence_base` not `offer_recurrence_paywindow`.
* New field `invreq_recurrence_cancel`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: Draft specification for recurring offers changed: old recurring offers will no longer work.
2025-10-01 15:31:30 +09:30
Rusty Russell
e7ea57e130 BOLT12: Remove start_any_period from recurrence_base.
Offer_absolute_expiry should be used if you want to require starting at the start.

Changelog-EXPERIMENTAL: Protocol: BOLT 12 recurrence `start_any_period` removed, use expiry if you need to restrict when they can start using the offer.
2025-10-01 15:31:30 +09:30
Rusty Russell
05005475e3 BOLT12: Remove years from recurrence.
Use months instead.

Changelog-EXPERIMENTAL: Protocol: BOLT 12 recurrence `years` removed; use 12 x months.
2025-10-01 15:31:30 +09:30
Matt Whitlock
4d47cc681d tests: do not leak file descriptors
Changelog-None
2025-09-15 11:19:17 +09:30
Rusty Russell
bc41d07443 Makefile: update so we know next version is v25.12
And add broken-log suppression to the tests which use deprecated features on their last gasp.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-09-04 12:10:29 +09:30
Lagrang3
7e5cf41b4e htlc_wire: fix crash when adding an HTLC
In line channeld/channeld_wiregen.c:832 `*added+i` is not a tal object hence
the instruction in common/htlc_wire.c:200 `tal_arr(ctx, struct tlv_field, 0);` crashes CLN.
This is fixed by stating that added_htlc is a a varsize_type.

Logs:

2025-08-16T02:25:28.640Z **BROKEN** lightningd: FATAL SIGNAL 6 (version v25.05-200-g79b959b)V
...
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/tal/tal.c:95 (call_error) 0x54f6bc
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/tal/tal.c:169 (check_bounds) 0x54f75a
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/tal/tal.c:178 (to_tal_hdr) 0x54f782
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/tal/tal.c:193 (to_tal_hdr_or_null) 0x54f7c7
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/tal/tal.c:471 (tal_alloc_) 0x54ffe4
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/tal/tal.c:517 (tal_alloc_arr_) 0x5500c4
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: common/htlc_wire.c:200 (fromwire_len_and_tlvstream) 0x48d63d
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: common/htlc_wire.c:234 (fromwire_added_htlc) 0x48dd23
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: channeld/channeld_wiregen.c:832 (fromwire_channeld_got_commitsig) 0x4c61fa
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: lightningd/peer_htlcs.c:2377 (peer_got_commitsig) 0x4549cb
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: lightningd/channel_control.c:1552 (channel_msg) 0x4140fe
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: lightningd/subd.c:560 (sd_msg_read) 0x461513
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:60 (next_plan) 0x544885
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:422 (do_plan) 0x544cea
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:439 (io_ready) 0x544d9d
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: ccan/ccan/io/poll.c:455 (io_loop) 0x54665d
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: lightningd/io_loop_with_timers.c:22 (io_loop_with_timers) 0x42d220
2025-08-16T02:25:28.640Z **BROKEN** lightningd: backtrace: lightningd/lightningd.c:1487 (main) 0x43280f

gdb inspection:
830             *added = num_added ? tal_arr(ctx, struct added_htlc, num_added) : NULL;
831             for (size_t i = 0; i < num_added; i++)
832                     fromwire_added_htlc(&cursor, &plen, *added + i);
(gdb) p i
$3 = 1

Changelog-None: crash introduced this release.
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
[ Added test, removed Changelog --RR ]
2025-08-27 14:14:31 +09:30
Rusty Russell
6c7c78ef38 pytest: test for crashing with HTLC added tlvs.
Reported-by: grubles
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-27 14:14:31 +09:30
Rusty Russell
70d19e852e bkpr: use list commands instead of subscribing to notifications.
This is reliable, meaning we should never get replayed events.

We have to reference count to make sure all commands are complete,
before we return.  In particular, annotating with descriptions can
involve several calls to list commands.  We need to give them the
results *after* this is all complete.

test_bookkeeping_descriptions() relied on log messages from
notifications, which now only happen when a command is called.  This
changes the test a bit.

Since we no longer subscribe to the balance_snapshot event, we
need to create the wallet account at initialization, as callers
expect it to exist.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-19 13:37:50 +09:30
Rusty Russell
f72df6da9c bkpr: cache accounts table in memory.
When we don't have our own db, we're going to need to keep this information
in memory (and the datastore).  As a first step, simply cache it in memory
and still write through to the db.

This introduces some changes:
1. The account structures are not temporary, but in the hash table (so don't steal them).
2. test_forward_pad_fees_and_cltv assumed ordering, which was a latent bug.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-19 13:37:50 +09:30
Rusty Russell
5345e71727 offers: fix fetchinvoice from using disconnected peers.
We didn't remove them from the graph if they were disconnected, leading to us trying to send an onion message to it:

```
➜  ~ lightning-cli fetchinvoice lno1pg7y7s69g98zq5rp09hh2arnypnx7u3qvf3nzut68pmkcet2xdm8s7ngw5ux2am4wqekwmtkddkkk7nyv45ryefexum82anr8phpp6qrse80qf0aara4slvcjxrvu6j2rp5ftmjy4yntlsmsutpkvkt6878sy4xtpdc0j42xp72an4cl0unvzm7ckx2e6ltlzlgeekh0hhe0mgs2qgpetp66ufc9pwln9gmyv0gk3ndpqvvtynef8adzm3lxv0astkxunjcqx0fsq8kmx5cz574ft45vcweaf3tffp90fjdfl9gkdh4s6xfxaz7srtmsju9gnr3xerjhjqw4xtsmp55f4jjsxxrch703kx020l6wn2ttcd24w5h8f2lz723lk2kpa8ftkernz7h2qqkd3zecz2jmhucwh555xf0np4w45zm8tlka4ktw6d3ne4l9u678y37d24xjcy3el53faulcu5tzzquxrxvcyrvzgk7tyjeapt8wu858m2msgdznhqxl8fps04lef9dc9c 1sat 
{
   "code": -1,
   "message": "onion msg: unknown next peer 024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605"
}
```

Fixes: https://github.com/ElementsProject/lightning/issues/8225
Changelog-Fixed: JSON-RPC: `fetchinvoice` is now more reliable.
2025-08-18 14:19:27 +09:30
Rusty Russell
b76d9b3d62 pytest: test for fetchinvoice when a onion-message-capable peer is disconnected.
```
FAILED tests/test_pay.py::test_fetchinvoice_autoconnect_if_disconnected - pyln.client.lightning.RpcError: RPC call failed: method: fetchinvoice, payload: {'offer': 'lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqypq5tn5v4ehghmxv46xx6rfdemx76trv40kzat5da3k7mnwv43hghmfve0kg6tnvdhkumn9vd6x2ep3zcssxhftzxfdlwsnfcgw2sy8t5mxa0ytcdfat2nkdwqvpy9nnsa9mzza'}, error: {'code': -1, 'message': 'onion msg: unknown next peer 022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59'}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-18 14:19:27 +09:30
Rusty Russell
7893c878b1 pytest: use _ not - in plugin options to zeroconf-selective.py.
This allows us to specify:

	l2.rpc.plugin_start(plugin_path, zeroconf_allow=l1.info['id'])

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-13 14:20:28 +09:30
Erick Cestari
6724db65de BOLT11: Make payment secret field ('s') mandatory
Make the payment secret field ('s') mandatory for BOLT11 payment requests,
implementing the requirement specified in BOLT11 spec PR #1242
(https://github.com/lightning/bolts/pull/1242).

This security enhancement prevents payment probing attacks by requiring
all invoices to include payment secrets. Changes include:

1. Adding validation in bolt11_decode_nosig() to reject invoices without
   the 's' field
2. Adding payment secrets to all test vectors
3. Updating expected encoded values in test cases to include payment secrets
4. Adding a specific test case that verifies proper rejection of invoices
   missing the payment secret field

Changelog-Changed: Made payment secret ('s' field) mandatory in BOLT11 payment requests for improved security.
2025-07-07 11:18:37 +09:30
Rusty Russell
66b6c111c2 pytest: fix up bolt11 tests to include s field.
It's about to be made compulsory.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-07-07 11:18:37 +09:30
Rusty Russell
89f411ca79 doc: be explicit (with tests!) on when we don't know amount_msat for listsendpays.
Sangbida and I traced back through ancient history: when the pay plugin was introduced
in 0.9.0 (2019!) it already used the amount_msat parameter (then called `msatoshi`),
so this case effectively "never happens".

But we added a test for it just in case.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-06-30 13:23:26 +09:30
Alex Myers
b74e156f58 pytest: search for less escaped log messages 2025-05-14 17:12:47 +09:30
Rusty Russell
3fc2a3b5d3 pytest: fix flake in test_pay_get_error_with_update.
We need to wait for exiting startup mode *before* closing channel, so it doesn't ignore
the disconnection of l3, otherwise we don't get a disabled update, and timeout waiting
at line 330:

    wait_for(lambda: not l1.is_channel_active(chanid2))

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-05-14 12:19:10 +09:30
Lagrang3
a90de8dcc7 sendonion: add total_amount_msat parameter
Changelog-Added: sendonion: a new paramter total_amount_msat to make MPP payments with sendpay and sendonion compatible.

[ Reordered to put new parameter at the end --RR ]
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2025-05-13 15:00:50 +09:30
Rusty Russell
e27dee0fc4 connectd: fix nagle disabling logic.
Our CORK logic was wrong, and it's better to use Nagle anyway:
we disable Nagle just before sending timing-critical messages.

Time for 100 (failed) payments:

Before:
	148.8573575

After:
	10.7356977

Note this revealed a timing problem in test_reject_invalid_payload: we would
miss the cause of the sendonion failure, and waitsendpay would be called
*after* it had failed, so simply returns "Payment failure reason unknown".

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Protocol: Removed 200ms latency from sending commit/revoke messages.
2025-05-08 14:01:38 +09:30
Rusty Russell
da56a8e657 pytest: don't use wrappers when we need dev arguments.
Pointed out by daywalker90, the introduction of wrappers caused
these tests to break.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-05-05 12:44:46 -07:00
Rusty Russell
db104aae92 lightningd: improve wait API by making details fields per-subsystem.
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>
2025-04-29 09:38:20 +09:30
Rusty Russell
6a9fd02d93 pytest: fix flake in test_blindedpath_privchan.
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>
2025-03-24 13:59:58 +10:30
Rusty Russell
922d78e89b pytest: fix flake in test_onionmessage_ratelimit.
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>
2025-03-24 13:59:58 +10:30
Rusty Russell
5ba5546192 pytest: fix flake in test_fetchinvoice
The sleep was simply allowing gossip to propagate, so (sometimes) l4 can connect to l3/l1.
We really want to suppress the blinded path on l2:

```
2025-03-03T05:25:16.6928072Z >       l4.rpc.call('fetchinvoice', {'offer': offer3['bolt12']})
2025-03-03T05:25:16.6928280Z
2025-03-03T05:25:16.6928367Z tests/test_pay.py:4540:
2025-03-03T05:25:16.6928609Z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-03-03T05:25:16.6928929Z contrib/pyln-testing/pyln/testing/utils.py:760: in call
...
2025-03-03T05:25:16.6956050Z E           pyln.client.lightning.RpcError: RPC call failed: method: fetchinvoice, payload: {'offer': 'lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqyqs5pn0venx2u3nzrhqxhftzxfdlwsnfcgw2sy8t5mxa0ytcdfat2nkdwqvpy9nnsa9mzzaqfwys22njn0v5g3jswhdh684hnlnkvd5pme28q5hgyyhshhmntd6qqsz40a4renm8a94r9xf5eez73ygcmendmd9utwmx0kzlp0lwd9sq98sqvutrneuljglxekynj2wdhpsa36ra3ae7uql9g79w9qqc0rqrunkystxgsz2reyay8hdtzwjew38w2u4xavpq2fm360hd75pkyuhpar0adgu93z8gn0jsyxganyhelch7savw6vrgqpj80cdc5qkwkaz0dk65cwyatgmhszpv72axqz6ldvcjq9crzevzpd3aeet607hq7sk0fvz0musdn7r96w6zcssytfzxcs2xkdy0lml0tzy0jzugmyj8kjn8zfzrgq9fsgurc72x82e'}, error: {'code': 1003, 'message': 'Failed: could not route or connect directly to blinded path at 035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d: {"code":400,"message":"Unable to connect, no address known for peer"}'}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-03-24 13:59:58 +10:30
Rusty Russell
ac596c8e08 offers: don't add blinded path from a disconnected peer.
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
2025-03-04 20:13:49 -06:00
Rusty Russell
d47b188cab pytest: add a test that we don't use an offline peer for offer paths.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-03-04 20:13:49 -06:00