Commit Graph

258 Commits

Author SHA1 Message Date
Rusty Russell de81a59b1e lightningd: mark explicitly what commands are dev-only.
And require --developer to use them.

Also refuse redirection to deprecated APIs if deprecated APIs are disabled! 

Changelog-Removed: `dev-sendcustommsg` (use `sendcustommsg`, which was added in v0.10.1)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-09-21 20:08:24 +09:30
Rusty Russell a9f26b7d07 common/daemon.c: remove #ifdef DEVELOPER in favor of runtime flag.
Also requires us to expose memleak when !DEVELOPER, however we only
ever used the memleak tracking when the LIGHTNINGD_DEV_MEMLEAK
environment variable was set, so keep that.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-09-21 20:08:24 +09:30
Rusty Russell 67a391f8d0 lightningd: pass --developer down to plugins, subdaemons when it set.
They might need to know this before they do anything, so cmdline seems most
natural.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-09-21 20:08:24 +09:30
Rusty Russell d5e86bf330 lightningd: don't print plugin deprecated options in --help.
We don't publish core deprecated options.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-08-18 20:29:34 +09:30
Rusty Russell f4e2d9a0ae lightningd: clean up properly if we fail to exec plugin.
Reported-by: @niftynei
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Plugins: we clean up properly if a plugin fails to start, and we don't kill all processes if it's from `plugin startdir`.
2023-08-18 13:18:49 +09:30
Lisa Neigut 55168e66ad Don't restart my machine if I add code to kill a failed plugin. 2023-08-18 13:18:49 +09:30
Rusty Russell f556be5d82 renepay: allow it to die gracefully without crashing lightningd.
Suggested-by: @Lagrang3
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-08-07 17:13:29 +09:30
Rusty Russell 8f2c9ce0ed lightningd: if a plugin disables at getmanfest time, use INFO log level.
This gets printed by default, so it's not lost!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-07-25 19:20:16 +09:30
Rusty Russell c074fe050f lightningd/log: clean up nomenclature.
`struct log` becomes `struct logger`, and the member which points to the
`struct log_book` becomes `->log_book` not `->lr`.

Also, we don't need to keep the log_book in struct plugin, since it has
access to ld's log_book.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-07-19 19:13:57 +09:30
Rusty Russell 46fc14c51d plugins: add support for wildcard subscription.
Requested-by: Shahana Farooqui @Shahana
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Plugins: plugins can subscribe to all notifications using "*".
2023-07-13 18:59:37 +09:30
Rusty Russell 0c4426a349 lightningd: remove deprecated_apis global, put into lightningd.
We usually have access to `ld`, so avoid the global.

The only place generic code needs it is for the json command struct,
and that already has accessors: add one for libplugin and lightningd
to tell it if deprecated apis are OK.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-07-09 16:49:48 +09:30
Rusty Russell 630dba8840 lightningd: call setconfig on plugins' dynamic options.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-20 20:08:25 +09:30
Rusty Russell b0c07dff2a plugin: allow plugins to set `dynamic` on options.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-20 20:08:25 +09:30
Rusty Russell e50e57712a setconfig: hook into plugin infrastructure for setconfig.
If it's a plugin opt, we'll need a callback, so reshuffle logic.  Also
add infra to map option name to plugin and option.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-20 20:08:25 +09:30
Rusty Russell ecc030f12d lightningd, libplugins: allocate opt strings from tmpctx, not NULL.
Previously, if these failed we always exited; once we have dymamic
configs this would be a (tiny) memory leak, so use tmpctx.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-20 20:08:25 +09:30
Rusty Russell e457681f3a lightningd: allow `false` as a default for flags.
defaults were deprecated in 0df97547dd, but that was a bit
harsh as several plugins do that (summary, for example).  So allow false, but warn
that we ignore anything else.

Reported-by: @microsatoshi on Discord.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Deprecated: Plugins: ...actually, `default` `false` still accepted on `flag` type parameters.
2023-06-07 13:16:08 +09:30
Matt Morehouse 4f30857401 lightningd: close plugin dir on return
Memory leak detected by ASan:

==880002==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 32816 byte(s) in 1 object(s) allocated from:
    #0 0x5039e7 in malloc (lightningd/lightningd+0x5039e7)
    #1 0x7f2e8c203884 in __alloc_dir (/lib64/libc.so.6+0xd2884)
2023-06-05 16:16:21 +02:00
Rusty Russell 3ac949d4c3 listconfigs: add `plugin` field if config is for a plugin.
I chose the full path name, not just the basename.

Suggested-by: @SimonVrouwe
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-03 10:50:29 +09:30
Rusty Russell 9cb2b2f13a listconfigs: show plugin options in 'configs' with normal options.
This integrates them with configvars properly: they almost "just work"
in listconfigs now, and we don't put them in a special sub-object
under their plugin.

Unfortunately, this means `listconfigs` now has a loose schema: any
plugin can add something to it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Plugins: reloaded plugins get passed any vars from configuration files.
Changelog-Deprecated: Config: boolean plugin options set to `1` or `0` (use `true` and `false` like non-plugin options).
2023-06-03 10:50:29 +09:30
Rusty Russell 0df97547dd lightningd: don't simply ignore defaults on flags, deprecate.
Changelog-Deprecated: Plugins: `default` no longer accepted on `flag` type parameters (it was silently ignored, so just don't set it).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-03 10:50:29 +09:30
Rusty Russell 45e16180bc lightningd: remove deprecated `null` for missing plugin options.
We leave the code in contrib/pyln-client/pyln/client/lightning.py to handle
msat null fields for now, though, for a bit more compatibility.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-06-03 10:50:29 +09:30
Rusty Russell a1e894a445 lightningd: treat JSON ids as direct tokens.
This avoids any confusion between primitive and string ids, and in
particular stops an issue with commando once it starts chaining ids,
that weird ids can be double-escaped and commando will not recognize
the response, leaving the client hanging.  It's the client's fault for
using a weird id, but it's still rude (and triggered by our tests!).

It also makes substituting the id in passthrough simpler, FTW.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2023-01-11 11:13:27 +10:30
Rusty Russell 19300de58f lightningd: correctly exit when an important-plugin fails to start.
This was found by tests/test_plugin.py::test_important_plugin and
was NOT a flake!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: only just committed
2022-11-30 15:47:31 +01:00
Rusty Russell 626998efce lightningd: don't timeout plugins if init is slow!
This is a minimal fix: we wait until all plugins reply from init before
continuing.  Really large or busy nodes can have other things monopolize
lightningd, then the timer goes off and we blame the plugin (which has
responded, we just haven't read it yet!).

The real answer is to have some timeouts only advance when we're idle,
or have them low-priority so we only activate them when we're idle (this
doesn't apply to all timers: some are probably important!).  But
this is a minimal fix for -rc3.

Fixes: https://github.com/ElementsProject/lightning/issues/5736
Changelog-Fixed: plugins: on large/slow nodes we could blame plugins for failing to answer init in time, when we were just slow.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-11-27 14:58:42 +01:00
Rusty Russell d5ce5cbab3 lightningd: only use non-numeric JSON ids if plugin says we can.
We also remember whether the id is a string or not, for replacement in
JSON passthrough.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-11-21 11:23:54 +01:00
Rusty Russell 24651f57ad plugins: set non_numeric_ids flag based on getmanifest `nonnumericids` field.
And document support for it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Plugins: `getmanfest` response can contain `nonnumericids` to indicate support for modern string-based JSON request ids.
Changelog-Deprecated: Plugins: numeric JSON request ids: modern ones will be strings (see doc/lightningd-rpc.7.md!)
2022-11-21 11:23:54 +01:00
Rusty Russell 3380f559f9 memleak: simplify API.
Mainly renaming.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-19 11:34:42 +09:30
Rusty Russell eceb9f4328 lightningd: wire plugin command JSON id through to plugin commands.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell a9557d5194 lightningd: derive JSONRPC ids from incoming id (append /cln:<method>#NNN).
Usually the calls are spontanous, so it's just "cln:<method>#NNN", but
json_invoice() calls listincoming, and json_checkmessage calls
listnodes, so those become "cli:invoice-<pid>/cln:listincoming#NNN".

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell 8fcf880e0f lightningd: explicitly remember if JSON id was a string.
This lets us use 'cmd->id' as an unquoted string (for building
new ids!).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell ed3f700991 lightningd: use string as json req ids when we create them.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell 99f2019a24 lightningd: add jsonrpc_request_start_raw instead of NULL method.
Since we want to use methodname to create id, don't overload it
for a raw request.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell 375215a141 lightningd: more graceful shutdown.
Be more graceful in shutting down: this should fix the issue where
bookkeeper gets upset that its commands are rejected during shutdown,
and generally make things more graceful.

1. Stop any new RPC connections.
2. Stop any per-peer daemons (channeld, etc).
3. Shut down plugins.
4. Stop all existing RPC connections.
5. Stop global daemons.
6. Free up peer, chanen HTLC datastructures.
7. Close database.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Plugins: RPC operations are now still available during shutdown.
2022-09-12 14:00:41 +02:00
Rusty Russell 29264e83fb lightningd: remove `use_proxy_always` parameter to plugin init.
Changelog-Removed: Plugins: plugin init `use_proxy_always` (deprecated v0.10.2)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-12 09:34:52 +09:30
Rusty Russell 733ce81bd4 plugins: require usage for plugin APIs.
Changelog-Removed: JSON-RPC: plugins must supply `usage` parameter (deprecated v0.7)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-12 09:34:52 +09:30
Rusty Russell 008a59b004 lightningd: ignore default if it's a literal 'null' JSON token.
I wondered how `tests/plugins/dblog.py` worked, since it is supposed to fail
unless the `dblog-file` arg is set:

```
@plugin.init()
def init(configuration, options, plugin):
    if not plugin.get_option('dblog-file'):
        raise RpcError("No dblog-file specified")
```

But it was set to "null".  That's because 'None' in python is turned into a literal
JSON "null", and we take that as the default value.

We also cleanup the popt->description double-assignment (a leftover
from when this was optional).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: plugins: setting the default value of a parameter to `null` is the same as not setting it (pyln plugins did this!).
2022-07-26 09:33:40 -07:00
Rusty Russell 401f1debc5 common: clean up json routine locations.
We have them split over common/param.c, common/json.c,
common/json_helpers.c, common/json_tok.c and common/json_stream.c.

Change that to:
* common/json_parse (all the json_to_xxx routines)
* common/json_parse_simple (simplest the json parsing routines, for cli too)
* common/json_stream (all the json_add_xxx routines)
* common/json_param (all the param and param_xxx routines)

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-15 12:24:00 -05:00
Vincenzo Palazzo b624c53051 plugin: add check on the type json object during the IO message handling 2022-07-14 12:49:23 -05:00
Simon Vrouwe cdf12d06ba lightningd: Make sure plugins don't register the same option "name"
The extra entry in opt_table would never be called, leaving plugins
clueless why options keep defaulting.

Note that option registration outside startup does nothing.
Instead, dynamic plugins can use `plugin start [second_parameter]` to pass options.
2022-07-10 21:09:41 -05:00
Simon Vrouwe 2fddfe3ffc lightningd: don't increment plugin state to NEEDS_INIT when error in getmanifest
Otherwise we hangs forever in startup when it was the last plugin, we would
miss destroy_plugin --> check_plugins_manifests --> io_break

e.g. when a plugin tries to register a bool option with a string as default value.
2022-07-10 21:09:41 -05:00
Simon Vrouwe 981fd2326a lightningd: convert plugin->cmd to absolute path, fail plugin early when non-existent
Otherwise different relative paths (e.g. /dir/plugin and /dir/../dir/plugin) to same plugin
executable would not be recognized as the same plugin
2022-07-10 21:09:41 -05:00
Rusty Russell 3f98cf3fce lightningd: track weird CI crash in test_important_plugin
Looks like we woke one of the startup io_loops early, and thus
we thought we'd finished connectd_activate and we hadn't.  This
caused us to use an uninitialized ld->announceable array, and
finally caused an assert fail in the main loop.

Make *every* loop assert that it was exited for the correct reason,
so if it happens again, we can maybe figure out what part of
the code to look at.

```
lightningd: lightningd/lightningd.c:1186: main: Assertion `io_loop_ret == ld' failed.
lightningd: FATAL SIGNAL 6 (version 4df66fa)
...
------------------------------- Valgrind errors --------------------------------
Valgrind error file: valgrind-errors.895509
==895509== Conditional jump or move depends on uninitialised value(s)
==895509==    at 0x22C58E: to_tal_hdr_or_null (tal.c:184)
==895509==    by 0x22D531: tal_bytelen (tal.c:637)
==895509==    by 0x1F10B6: towire_gossipd_init (gossipd_wiregen.c:100)
==895509==    by 0x13AC6E: gossip_init (gossip_control.c:254)
==895509==    by 0x1497EC: main (lightningd.c:1090)
==895509== 
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-06-27 17:21:35 +09:30
Rusty Russell e2f0ca9cbe lightningd: don't add null for unset plugin options.
In general, we don't like to use `null` in JSON: simply omit the
field.  I found this one because it broke our 'msat' parsing (made
stricter in followup) which doesn't allow `null`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Deprecated: `listconfigs` `plugins` `options` which are not set are omitted, not `null`.
2022-06-21 06:52:35 +09:30
Rusty Russell 8b62e2584f connectd: remove enable-autotor-v2-mode option
Changelog-Removed: lightningd: removed `enable-autotor-v2-mode` option (deprecated v0.10.1)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-05-18 10:15:36 +09:30
Simon Vrouwe 426ff0abff lightningd: cleanup obsolete plugins->shutdown flag
After leaving the main event loop, the only path to destroy_plugin
goes via shutdown_plugins.
2021-12-14 09:33:10 +10:30
Simon Vrouwe f936fa926f plugins: simplify shutdown loop, simply close the db
The only thing that needs ld->wallet after this is destroy_invoices_waiter (off jsonrpc)
Could not find any other destructors (destroy_*) that need wallet or db access after this.
Any db access would now segfault.
2021-12-14 09:33:10 +10:30
Rusty Russell 484222b0a1 daemons: remove unused functions or make static.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2021-12-06 10:05:39 +10:30
Rusty Russell 4ffda340d3 check: make sure all files outside contrib/ include "config.h" first.
And turn "" includes into full-path (which makes it easier to put
config.h first, and finds some cases check-includes.sh missed
previously).

config.h sets _GNU_SOURCE which really needs to be done before any
'#includes': we mainly got away with it with glibc, but other platforms
like Alpine may have stricter requirements.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2021-12-06 10:05:39 +10:30
Simon Vrouwe 209614677a JSON RPC: In the shutdown loop, ignore plugin responses to JSON RPC requests 2021-11-30 13:34:44 +10:30
Simon Vrouwe 5f69674faa lightningd: shutdown plugins after subdaemons and assert no write access to db
because:
    - shutdown_subdaemons can trigger db write, comments in that function say so at least
    - resurrecting the main event loop with subdaemons still running is counter productive
      in shutting down activity (such as htlc's, hook_calls etc.)
    - custom behavior injected by plugins via hooks should be consistent, see test
      in previous commmit

    IDEA:

    in shutdown_plugins, when starting new io_loop:

    - A plugin that is still running can return a jsonrpc_request response, this triggers
      response_cb, which cannot be handled because subdaemons are gone -> so any response_cb should be blocked/aborted

    - jsonrpc is still there, so users (such as plugins) can make new jsonrpc_request's which
      cannot be handled because subdaemons are gone -> so new rpc_request should also be blocked

    - But we do want to send/receive notifications and log messages (handled in jsonrpc as jsonrpc_notification)
      as these do not trigger subdaemon calls or db_write's
      Log messages and notifications do not have "id" field, where jsonrpc_request *do* have an "id" field

    PLAN (hypothesis):
    - hack into plugin_read_json_one OR plugin_response_handle to filter-out json with
      an "id" field, this should
      block/abandon any jsonrpc_request responses (and new jsonrpc_requests for plugins?)

  Q. Can internal (so not via plugin) jsonrpc_requests called in the main io_loop return/revive in
     the shutdown io_loop?
  A. No. All code under lightningd/ returning command_still_pending depends on either a subdaemon, timer or
     plugin. In shutdown loop the subdaemons are dead, timer struct cleared and plugins will be taken
     care of (in next commits).

 fixup: we can only io_break the main io_loop once
2021-11-30 13:34:44 +10:30