136 Commits

Author SHA1 Message Date
Rusty Russell
8b9020d7b9 global: use clock_time in place of time_now().
Except for tracing, that sticks with time_now().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-13 21:21:29 +10:30
Rusty Russell
f8fd97fb5d global: replace randombytes_buf() with randbytes() wrapper.
This allows us to override it for deterministic results.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-13 21:21:29 +10:30
Rusty Russell
6e5cb299dd global: remove unnecessary includes from C files.
Basically, `devtools/reduce-includes.sh */*.c`.

Build time from make clean (RUST=0) (includes building external libs):

Before:
	real    0m38.944000-40.416000(40.1131+/-0.4)s
	user    3m6.790000-17.159000(15.0571+/-2.8)s
	sys     0m35.304000-37.336000(36.8942+/-0.57)s
After:
	real    0m37.872000-39.974000(39.5466+/-0.59)s
	user    3m1.211000-14.968000(12.4556+/-3.9)s
	sys     0m35.008000-36.830000(36.4143+/-0.5)s

Build time after touch config.vars (RUST=0):

Before:
	real    0m19.831000-21.862000(21.5528+/-0.58)s
	user    2m15.361000-30.731000(28.4798+/-4.4)s
	sys     0m21.056000-22.339000(22.0346+/-0.35)s

After:
	real    0m18.384000-21.307000(20.8605+/-0.92)s
	user    2m5.585000-26.843000(23.6017+/-6.7)s
	sys     0m19.650000-22.003000(21.4943+/-0.69)s

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
f6a4e79420 global: remove unnecessary includes from headers.
Each header should only include the other headers it needs to compile;
`devtools/reduce-includes.sh */*.h` does this.  The C files then need
additional includes if they don't compile.

And remove the entirely useless wire/onion_wire.h, which only serves to include wire/onion_wiregen.h.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
512f328730 wire: update to slight spec neating.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-01 15:31:30 +09:30
Rusty Russell
0d18b82dae plugins: cancelrecurringinvoice command.
`fetchinvoice` variant, for setting invreq_recurrence_cancel instead.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: `cancelrecurringinvoice` command to send new "don't expect any more invoice requests" msg to recurring bolt12 invoices.
2025-10-01 15:31:30 +09:30
Rusty Russell
5a73bd34e5 plugins/fetchinvoice: allow send_message() to say "don't expect a reply"
We're going to want this for sending invreq_recurrence_cancel invoice_requests.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-01 15:31:30 +09:30
Rusty Russell
4e7c2fcf32 plugins/fetchinvoice: extract bip353 parsing to param helper.
We're going to want this for cancelrecurringinvoice.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-01 15:31:30 +09:30
Rusty Russell
551ecdf7ab plugins/fetchinvoice: extract recurrence invreq_metadata routine.
We're going to want this for cancelrecurringinvoice.

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
559e3fc447 common: fix bolt12 quotes to bring them up-to-date.
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
e832784cba BOLTS: update which fixes BIP353 quotes, missing invreq field in invoices.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-03-18 14:30:58 +10:30
Rusty Russell
c3362b057c BOLT12: remove -offers from bolt12 quotes, update them.
Typo fixes and wording changes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-02-11 20:19:01 -06:00
Rusty Russell
c22cc11af5 fetchinvoice: allow user to specify bip353 name corresponding to how they got offer.
Changelog-Added: JSON-RPC: `fetchinvoice` BIP 353 name support (`bip353`).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-02-11 20:19:01 -06:00
Rusty Russell
ba7bf334b1 fetchinvoice: check better.
We do a lot more parameter checking than simply parsing, so use
param_check().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-19 22:54:22 +01:00
Vincenzo Palazzo
6f0dbbb20f bolt12: allow to inject payer_metadata
Payer metadata is a field that controls the payer ID
provided during the fetchinvoice process.

There are use cases where this is highly useful, such as
proving that the payer has paid for the correct item.

Imagine visiting a merchant's website to pay for multiple offers, where
one of these offers is a default offer (with no description and no set amount).

In this scenario, the merchant could claim not to have received
payment for a specific item. Since the same offer may be used to
fetch invoices for different products, there needs to be a way to
identify which product the invoice corresponds to.

With this commit, it will be possible to inject payer metadata,
which helps solve the issue described above.

For example, possible payer metadata could be `to_hex(b"{payer_node_id}.{product_id}.{created_at}")`.

Changelog-Added: JSON-RPC: `fetchinvoice` allows setting invreq_metadata via `payer_metadata` parameter.
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2024-11-19 22:54:22 +01:00
Rusty Russell
46b0eb108b plugins: don't check for experimental-offers option: it's the default now.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 10:42:54 +01:00
Rusty Russell
c797b6fb20 libplugin: add method string to jsonrpc callbacks, implement generic helpers.
Without knowing what method was called, we can't have useful general logging
methods, so go through the pain of adding "const char *method" everywhere,
and add:

1. ignore_and_complete - we're done when jsonrpc returned
2. log_broken_and_complete - we're done, but emit BROKEN log.
3. plugin_broken_cb - if this happens, fail the plugin.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Rusty Russell
c5099b1647 libplugin: clean up API.
When we used to allow cmd to be NULL, we had to hand the plugin
everywhere.  We no longer do.

1. Various jsonrpc_ functions no longer need the plugin arg.
2. send_outreq no longer needs a plugin arg.
3. The init function takes a command, not a plugin.
4. Remove command_deprecated_in_nocmd_ok.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Rusty Russell
7ce30e2873 libplugin: make timers have a "command" context.
This is cleaner: everything can now be associated with a command
context.

You're supposed to eventually dispose of it using timer_complete().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Vincenzo Palazzo
6309503692 bolt12: fix typo about parameters name in err str
Changelog-Fixed: bolt12: fix typo about parameters name in err str
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2024-11-03 21:38:10 +10:30
Rusty Russell
8dbc1c5f2e offers: fix crash when receiving response to offer without offer_issuer_id
Now we actually check the other fields too, as per BOLT!

Reported-by: https://github.com/hMsats
Fixes: #7513
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-06 19:09:27 -07:00
Rusty Russell
f77d4d7097 offers: fix flake in fetchinvoice.
In CI, this would sometimes fail: we would timeout waiting for the
fetchinvoice reply.  Never happened locally, so was annoying to debug.

What happened was simple: we called injectonionmessage then when it
returned, put the "sent" object in the linked list so we could recognize
any reply onion messages.

However, we were getting that reply before the plugin processed the response
to injectonionmessage.  This is possible because there are two fds for
plugins: one for it to receive notifications and hooks (like onion messages)
and one for normal RPC usage (like commands to inject onion messages).

The fix is simple: put in the list *before* calling JSON RPC.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-05 16:35:15 +02:00
Rusty Russell
bf549130d6 global: update BOLT12 quotes.
This is a final sweep to match the current BOLT12 text:

	1563d13999d342680140c693de0b9d65aa522372 ("More bolt12 test vectors.")

Only two code changes, to change the order of checks to match the bolt,
and to give a warning on decode if a path is empty.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
f2a7b19281 plugins/offers: handle invreq_paths in invoice_requests, set them if necessary.
Changelog-EXPERIMENTAL: offers: `invoicerequest` will set a blinded path if we're an unannounced node.
Changelog-EXPERIMENTAL: offers: `sendinvoice` will use a blinded path in an invoice_request, if specified.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
71270ae795 lightningd: make the caller set invreq_metadata and invreq_payer_id for createinvoicerequest.
It's an internal undocumented interface, which makes this change less painful.

We *do* check that the invreq_metadata maps to the given invreq_payer_id, which would
is required for us to sign it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
fa33a2fece lightningd: make plugins set metadata for invoice requests.
They can do it now: before it would have been awkward to look up previous
payments to match it up for recurring offers (which need to use the same
key, hence the same invreq_metadata).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
d740795139 common/bolt12: allow missing offer_issuer_id.
The latest spec allows this to be omitted iff there is a blinded path
and it would be made up anyway.

In that case, the key they will use to sign the invoice will be the final
blinded key in the path we use.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
925e90ee8b wire: rename "offer_node_id" to "offer_issuer_id" to match latest BOLT.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
ef2905895b offers: fix invoice return comparison.
This mistake was revealed when we start using experimental range for recurrence
(next commit).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-01 12:31:48 +09:30
Rusty Russell
88024fa8d6 common/bolt12, offers plugin: handle experimental ranges in bolt12 correctly.
The latest draft allows these experimental ranges, which involves more
changes than I expected.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: offers: handle experimental ranges in offers/invoice_requests/invoices.
2024-07-23 09:54:47 +09:30
Rusty Russell
b29b96aae8 common: hoist scidd->pubkey conversion function into gossmap.
We will want to use it in the pay plugin too.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-18 10:53:55 +09:30
Rusty Russell
e8b959ac77 plugins/offers: allow reversal of a single-element path for reply.
Don't refuse, this will happen if we are the head of the blinded path,
for example.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-18 10:53:55 +09:30
Rusty Russell
dacf81672e plugins/offers: improve reply path logic.
We generate a reply path by simply reversing the outgoing path:

	A->B->C gives reply path B->A
	A->B gives reply path A

But if we are not a public node, we can't use ourselves as the first
entry of the reply path: this happens if we directly connect to the
head of a blinded path (as we now support).

In this case, give the entire path as a blinded path.  We could do
this all the time, but there are some cases where nodes don't like
sending replies where the node itself is the head of the blinded
path (like CLN v24.05 or before!).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-17 10:57:11 +02:00
Rusty Russell
92eb84d45f fetchinvoice: don't call establish_onion_path ourselves, now send_message does it.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-17 10:57:11 +02:00
Rusty Russell
1a4256842c fetchinvoice: handle blinded paths in offers.
We iterate through the blinded paths until we can use one, and because we use
the modern code, we properly join paths if we need to route more than one hop
to reach the start of the blinded path.

Changelog-EXPERIMENTAL: fixed: fetchinvoice tries all blinded paths until one is usable, and handles case where we have to route more than one hop to reach the entry point.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-17 10:57:11 +02:00
Rusty Russell
ef641e81c6 fetchinvoice: don't stash path in sent object, hand directly.
Simplification.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-17 10:57:11 +02:00
Rusty Russell
a6cfdea71b fetchinvoice: use common/onion_message routines.
This is significantly simpler, too.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-17 10:57:11 +02:00
Rusty Russell
d664d52342 plugins/offers: neaten fetchinvoice integration.
We already parse some fields, so hand them directly rather than
having fetchinvoice behave as if it's a raw hook.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-17 10:57:11 +02:00
Rusty Russell
a782ea75b5 plugins: move fetchinvoice functionality into offers plugin.
This means only a single gossmap, and they already share the fetchinvoice-noconnect option
and autoconnect code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Plugins: the `fetchinvoice` plugin has been combined into the `offers` plugin.
2024-07-17 10:57:11 +02:00
Rusty Russell
0c7ce27a39 plugins/offers: establish_onion_path can have a simple boolean arg for connect_disable.
It's always the same string, so simplify the interface.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-09 15:09:29 +02:00
Rusty Russell
757e6f8a9b libplugin: allow display of default values.
This means we can see the values in listconfigs, even if we haven't set
them yet.

In particular, we now see the following:

* autoclean-cycle.value_int=3600
* bitcoin-rpcclienttimeout.value_int=60
* bitcoin-retry-timeout.value_int=60
* funder-max-their-funding.value_str=4294967295sat
* funder-per-channel-min.value_str=10000sat
* funder-reserve-tank.value_str=0sat
* funder-fund-probability.value_int=100

Changelog-Changed: plugins: libplugin now shows plugin option default values (where they're non-trivial)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-15 15:50:54 -05:00
Rusty Russell
9aed594177 pytest: test fetchinvoice reply path which is not a direct peer.
Our fetchinvoice always creates a reply path which terminates at their peer,
so we need a dev overrride for that.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-14 18:16:26 -05:00
Rusty Russell
2e1274ba76 plugins/fetchinvoice: use new generic connect-if-needed infrastructure.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-14 18:16:26 -05:00
Rusty Russell
b94be330e6 plugins: generalize "connect if we can't route" logic, link into offers plugin.
We're going to dynamically connect if we need to, to reply to incoming invoice_requests.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-14 18:16:26 -05:00
Rusty Russell
e338452c19 offers: handle scid in blinded reply path first_node_id field.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: offers: we now understand blinded paths which use a short-channel-id(+direction) as entry point.
2024-05-12 19:11:43 -05:00
Rusty Russell
cb2c4963f2 bolt12: allow first_node_id in blinded path to be a scid.
We don't actually support it yet, but this threads through the type change,
puts it in "decode" etc.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-12 19:11:43 -05:00
Rusty Russell
7eb72c5924 plugins/fetchinvoice: remove "blindedpath" command altogether, since we're the only user.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-12 19:11:43 -05:00