mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 13:25:43 +01:00
libplugin: make init return a string.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: libplugin: init can return a non-NULL string to disable the plugin.
This commit is contained in:
parent
529ae0d766
commit
27c006f7aa
@ -64,7 +64,7 @@ static struct command_result *json_autocleaninvoice(struct command *cmd,
|
|||||||
expired_by, cycle_seconds));
|
expired_by, cycle_seconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(struct plugin *p,
|
static const char *init(struct plugin *p,
|
||||||
const char *buf UNUSED, const jsmntok_t *config UNUSED)
|
const char *buf UNUSED, const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
if (cycle_seconds) {
|
if (cycle_seconds) {
|
||||||
@ -73,6 +73,8 @@ static void init(struct plugin *p,
|
|||||||
do_clean, p);
|
do_clean, p);
|
||||||
} else
|
} else
|
||||||
plugin_log(p, LOG_DBG, "autocleaning not active");
|
plugin_log(p, LOG_DBG, "autocleaning not active");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct plugin_command commands[] = { {
|
static const struct plugin_command commands[] = { {
|
||||||
|
@ -870,12 +870,14 @@ static void wait_and_check_bitcoind(struct plugin *p)
|
|||||||
tal_free(cmd);
|
tal_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(struct plugin *p, const char *buffer UNUSED,
|
static const char *init(struct plugin *p, const char *buffer UNUSED,
|
||||||
const jsmntok_t *config UNUSED)
|
const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
wait_and_check_bitcoind(p);
|
wait_and_check_bitcoind(p);
|
||||||
plugin_log(p, LOG_INFORM,
|
plugin_log(p, LOG_INFORM,
|
||||||
"bitcoin-cli initialized and connected to bitcoind.");
|
"bitcoin-cli initialized and connected to bitcoind.");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct plugin_command commands[] = {
|
static const struct plugin_command commands[] = {
|
||||||
|
@ -1346,12 +1346,14 @@ static const struct plugin_command commands[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void init(struct plugin *p, const char *buf UNUSED,
|
static const char *init(struct plugin *p, const char *buf UNUSED,
|
||||||
const jsmntok_t *config UNUSED)
|
const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
rpc_scan(p, "getinfo",
|
rpc_scan(p, "getinfo",
|
||||||
take(json_out_obj(NULL, NULL, NULL)),
|
take(json_out_obj(NULL, NULL, NULL)),
|
||||||
"{id:%}", JSON_SCAN(json_to_node_id, &local_id));
|
"{id:%}", JSON_SCAN(json_to_node_id, &local_id));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct plugin_hook hooks[] = {
|
static const struct plugin_hook hooks[] = {
|
||||||
|
@ -92,7 +92,7 @@ REGISTER_PAYMENT_MODIFIER(keysend, struct keysend_data *, keysend_init,
|
|||||||
* End of keysend modifier
|
* End of keysend modifier
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
static void init(struct plugin *p, const char *buf UNUSED,
|
static const char *init(struct plugin *p, const char *buf UNUSED,
|
||||||
const jsmntok_t *config UNUSED)
|
const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
rpc_scan(p, "getinfo", take(json_out_obj(NULL, NULL, NULL)),
|
rpc_scan(p, "getinfo", take(json_out_obj(NULL, NULL, NULL)),
|
||||||
@ -102,6 +102,8 @@ static void init(struct plugin *p, const char *buf UNUSED,
|
|||||||
take(json_out_obj(NULL, "config", "max-locktime-blocks")),
|
take(json_out_obj(NULL, "config", "max-locktime-blocks")),
|
||||||
"{max-locktime-blocks:%}",
|
"{max-locktime-blocks:%}",
|
||||||
JSON_SCAN(json_to_number, &maxdelay_default));
|
JSON_SCAN(json_to_number, &maxdelay_default));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct payment_modifier *pay_mods[8] = {
|
struct payment_modifier *pay_mods[8] = {
|
||||||
|
@ -71,7 +71,7 @@ struct plugin {
|
|||||||
struct plugin_option *opts;
|
struct plugin_option *opts;
|
||||||
|
|
||||||
/* Anything special to do at init ? */
|
/* Anything special to do at init ? */
|
||||||
void (*init)(struct plugin *p,
|
const char *(*init)(struct plugin *p,
|
||||||
const char *buf, const jsmntok_t *);
|
const char *buf, const jsmntok_t *);
|
||||||
/* Has the manifest been sent already ? */
|
/* Has the manifest been sent already ? */
|
||||||
bool manifested;
|
bool manifested;
|
||||||
@ -878,8 +878,12 @@ static struct command_result *handle_init(struct command *cmd,
|
|||||||
tal_free(opt);
|
tal_free(opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->init)
|
if (p->init) {
|
||||||
p->init(p, buf, configtok);
|
const char *disable = p->init(p, buf, configtok);
|
||||||
|
if (disable)
|
||||||
|
return command_success(cmd, json_out_obj(cmd, "disable",
|
||||||
|
disable));
|
||||||
|
}
|
||||||
|
|
||||||
if (with_rpc)
|
if (with_rpc)
|
||||||
io_new_conn(p, p->rpc_conn->fd, rpc_conn_init, p);
|
io_new_conn(p, p->rpc_conn->fd, rpc_conn_init, p);
|
||||||
@ -1296,8 +1300,9 @@ static struct io_plan *stdout_conn_init(struct io_conn *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct plugin *new_plugin(const tal_t *ctx,
|
static struct plugin *new_plugin(const tal_t *ctx,
|
||||||
void (*init)(struct plugin *p,
|
const char *(*init)(struct plugin *p,
|
||||||
const char *buf, const jsmntok_t *),
|
const char *buf,
|
||||||
|
const jsmntok_t *),
|
||||||
const enum plugin_restartability restartability,
|
const enum plugin_restartability restartability,
|
||||||
bool init_rpc,
|
bool init_rpc,
|
||||||
struct feature_set *features,
|
struct feature_set *features,
|
||||||
@ -1365,7 +1370,7 @@ static struct plugin *new_plugin(const tal_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void plugin_main(char *argv[],
|
void plugin_main(char *argv[],
|
||||||
void (*init)(struct plugin *p,
|
const char *(*init)(struct plugin *p,
|
||||||
const char *buf, const jsmntok_t *),
|
const char *buf, const jsmntok_t *),
|
||||||
const enum plugin_restartability restartability,
|
const enum plugin_restartability restartability,
|
||||||
bool init_rpc,
|
bool init_rpc,
|
||||||
|
@ -277,8 +277,9 @@ char *flag_option(const char *arg, bool *i);
|
|||||||
|
|
||||||
/* The main plugin runner: append with 0 or more plugin_option(), then NULL. */
|
/* The main plugin runner: append with 0 or more plugin_option(), then NULL. */
|
||||||
void NORETURN LAST_ARG_NULL plugin_main(char *argv[],
|
void NORETURN LAST_ARG_NULL plugin_main(char *argv[],
|
||||||
void (*init)(struct plugin *p,
|
const char *(*init)(struct plugin *p,
|
||||||
const char *buf, const jsmntok_t *),
|
const char *buf,
|
||||||
|
const jsmntok_t *),
|
||||||
const enum plugin_restartability restartability,
|
const enum plugin_restartability restartability,
|
||||||
bool init_rpc,
|
bool init_rpc,
|
||||||
struct feature_set *features,
|
struct feature_set *features,
|
||||||
|
@ -665,7 +665,7 @@ static struct command_result *json_decode(struct command *cmd,
|
|||||||
return command_finished(cmd, response);
|
return command_finished(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(struct plugin *p,
|
static const char *init(struct plugin *p,
|
||||||
const char *buf UNUSED,
|
const char *buf UNUSED,
|
||||||
const jsmntok_t *config UNUSED)
|
const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
@ -681,6 +681,8 @@ static void init(struct plugin *p,
|
|||||||
rpc_scan(p, "listconfigs",
|
rpc_scan(p, "listconfigs",
|
||||||
take(json_out_obj(NULL, "config", "cltv-final")),
|
take(json_out_obj(NULL, "config", "cltv-final")),
|
||||||
"{cltv-final:%}", JSON_SCAN(json_to_number, &cltv_final));
|
"{cltv-final:%}", JSON_SCAN(json_to_number, &cltv_final));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct plugin_command commands[] = {
|
static const struct plugin_command commands[] = {
|
||||||
|
@ -1902,7 +1902,7 @@ static struct command_result *json_listpays(struct command *cmd,
|
|||||||
return send_outreq(cmd->plugin, req);
|
return send_outreq(cmd->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(struct plugin *p,
|
static const char *init(struct plugin *p,
|
||||||
const char *buf UNUSED, const jsmntok_t *config UNUSED)
|
const char *buf UNUSED, const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
rpc_scan(p, "getinfo", take(json_out_obj(NULL, NULL, NULL)),
|
rpc_scan(p, "getinfo", take(json_out_obj(NULL, NULL, NULL)),
|
||||||
@ -1912,6 +1912,8 @@ static void init(struct plugin *p,
|
|||||||
take(json_out_obj(NULL, "config", "max-locktime-blocks")),
|
take(json_out_obj(NULL, "config", "max-locktime-blocks")),
|
||||||
"{max-locktime-blocks:%}",
|
"{max-locktime-blocks:%}",
|
||||||
JSON_SCAN(json_to_number, &maxdelay_default));
|
JSON_SCAN(json_to_number, &maxdelay_default));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct payment_modifier *paymod_mods[] = {
|
struct payment_modifier *paymod_mods[] = {
|
||||||
|
@ -9,10 +9,11 @@
|
|||||||
* spending from the onchain wallet. */
|
* spending from the onchain wallet. */
|
||||||
|
|
||||||
static
|
static
|
||||||
void spender_init(struct plugin *p, const char *b, const jsmntok_t *t)
|
const char *spender_init(struct plugin *p, const char *b, const jsmntok_t *t)
|
||||||
{
|
{
|
||||||
openchannel_init(p, b, t);
|
openchannel_init(p, b, t);
|
||||||
/* whatever_init(p, b, t); */
|
/* whatever_init(p, b, t); */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
const char *name_option;
|
const char *name_option;
|
||||||
|
static bool self_disable = false;
|
||||||
|
|
||||||
static struct command_result *json_helloworld(struct command *cmd,
|
static struct command_result *json_helloworld(struct command *cmd,
|
||||||
const char *buf,
|
const char *buf,
|
||||||
@ -86,10 +86,15 @@ static struct command_result *json_testrpc(struct command *cmd,
|
|||||||
return send_outreq(cmd->plugin, req);
|
return send_outreq(cmd->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(struct plugin *p,
|
static const char *init(struct plugin *p,
|
||||||
const char *buf UNUSED, const jsmntok_t *config UNUSED)
|
const char *buf UNUSED,
|
||||||
|
const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
plugin_log(p, LOG_DBG, "test_libplugin initialised!");
|
plugin_log(p, LOG_DBG, "test_libplugin initialised!");
|
||||||
|
|
||||||
|
if (self_disable)
|
||||||
|
return "Disabled via selfdisable option";
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct plugin_command commands[] = { {
|
static const struct plugin_command commands[] = { {
|
||||||
@ -149,5 +154,9 @@ int main(int argc, char *argv[])
|
|||||||
"string",
|
"string",
|
||||||
"Who to say hello to.",
|
"Who to say hello to.",
|
||||||
charp_option, &name_option),
|
charp_option, &name_option),
|
||||||
|
plugin_option("selfdisable",
|
||||||
|
"flag",
|
||||||
|
"Whether to disable.",
|
||||||
|
flag_option, &self_disable),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
@ -2326,19 +2326,26 @@ def test_pyln_request_notify(node_factory):
|
|||||||
def test_self_disable(node_factory):
|
def test_self_disable(node_factory):
|
||||||
"""Test that plugin can disable itself without penalty.
|
"""Test that plugin can disable itself without penalty.
|
||||||
"""
|
"""
|
||||||
plugin_path = os.path.join(
|
# This disables in response to getmanifest.
|
||||||
os.path.dirname(__file__), 'plugins/test_selfdisable'
|
p1 = os.path.join(
|
||||||
|
os.path.dirname(__file__), 'plugins/test_selfdisable_after_getmanifest'
|
||||||
)
|
)
|
||||||
l1 = node_factory.get_node(options={'important-plugin': plugin_path})
|
# This disables in response to init.
|
||||||
|
p2 = os.path.join(os.getcwd(), "tests/plugins/test_libplugin")
|
||||||
|
l1 = node_factory.get_node(options={'important-plugin': [p1, p2], 'selfdisable': None})
|
||||||
|
|
||||||
# Could happen before it gets set up.
|
# Could happen before it gets set up.
|
||||||
l1.daemon.logsearch_start = 0
|
l1.daemon.logsearch_start = 0
|
||||||
l1.daemon.wait_for_log('test_selfdisable: disabled itself: "Self-disable test after getmanifest"')
|
l1.daemon.wait_for_logs(['test_selfdisable_after_getmanifest: disabled itself: "Self-disable test after getmanifest"',
|
||||||
|
'test_libplugin: disabled itself at init: Disabled via selfdisable option'])
|
||||||
|
|
||||||
assert plugin_path not in [p['name'] for p in l1.rpc.plugin_list()['plugins']]
|
assert p1 not in [p['name'] for p in l1.rpc.plugin_list()['plugins']]
|
||||||
|
assert p2 not in [p['name'] for p in l1.rpc.plugin_list()['plugins']]
|
||||||
|
|
||||||
# Also works with dynamic load attempts
|
# Also works with dynamic load attempts
|
||||||
with pytest.raises(RpcError, match="Self-disable test after getmanifest"):
|
with pytest.raises(RpcError, match="Self-disable test after getmanifest"):
|
||||||
l1.rpc.plugin_start(plugin_path)
|
l1.rpc.plugin_start(p1)
|
||||||
|
|
||||||
# Now test the disable-in-init-response.
|
# Also works with dynamic load attempts
|
||||||
|
with pytest.raises(RpcError, match="Disabled via selfdisable option"):
|
||||||
|
l1.rpc.plugin_start(p2, selfdisable=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user