diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index b9c0131c8..5df163d64 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -7,10 +7,12 @@ #include "bitcoind.h" #include "lightningd.h" #include "log.h" +#include #include #include #include #include +#include #include #include #include @@ -22,6 +24,7 @@ #include #include #include +#include /* Bitcoind's web server has a default of 4 threads, with queue depth 16. * It will *fail* rather than queue beyond that, so we must not stress it! @@ -30,6 +33,26 @@ */ #define BITCOIND_MAX_PARALLEL 4 +/* The names of the request we can make to our Bitcoin backend. */ +static const char *methods[] = {"getchaininfo", "getrawblockbyheight", + "sendrawtransaction", "getutxout", + "getfeerate"}; + +void bitcoind_check_commands(struct bitcoind *bitcoind) +{ + size_t i; + struct plugin *p; + + for (i = 0; i < ARRAY_SIZE(methods); i++) { + p = find_plugin_for_command(bitcoind->ld, methods[i]); + if (p == NULL) { + fatal("Could not access the plugin for %s, is a " + "Bitcoin plugin (by default plugins/bcli) " + "registered ?", methods[i]); + } + } +} + /* Add the n'th arg to *args, incrementing n and keeping args of size n+1 */ static void add_arg(const char ***args, const char *arg) { diff --git a/lightningd/bitcoind.h b/lightningd/bitcoind.h index 7812f6e06..5b1e22966 100644 --- a/lightningd/bitcoind.h +++ b/lightningd/bitcoind.h @@ -182,4 +182,6 @@ void bitcoind_gettxout(struct bitcoind *bitcoind, void bitcoind_getclientversion(struct bitcoind *bitcoind); +void bitcoind_check_commands(struct bitcoind *bitcoind); + #endif /* LIGHTNING_LIGHTNINGD_BITCOIND_H */ diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 9b5c9ff7a..fa7837ae3 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -955,6 +955,9 @@ void setup_topology(struct chain_topology *topo, topo->min_blockheight = min_blockheight; topo->max_blockheight = max_blockheight; + /* This waits for bitcoind. */ + bitcoind_check_commands(topo->bitcoind); + /* Make sure bitcoind is started, and ready */ wait_for_bitcoind(topo->bitcoind); diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 1dc9f2d8c..fbfd6caad 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -611,21 +611,21 @@ static void plugin_rpcmethod_cb(const char *buffer, command_raw_complete(cmd, response); } -static struct plugin *find_plugin_for_command(struct command *cmd) +struct plugin *find_plugin_for_command(struct lightningd *ld, + const char *cmd_name) { - struct plugins *plugins = cmd->ld->plugins; + struct plugins *plugins = ld->plugins; struct plugin *plugin; /* Find the plugin that registered this RPC call */ list_for_each(&plugins->plugins, plugin, list) { for (size_t i=0; imethods); i++) { - if (streq(cmd->json_cmd->name, plugin->methods[i])) + if (streq(cmd_name, plugin->methods[i])) return plugin; } } - /* This should never happen, it'd mean that a plugin didn't - * cleanup after dying */ - abort(); + + return NULL; } static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd, @@ -641,7 +641,9 @@ static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd, if (cmd->mode == CMD_CHECK) return command_param_failed(); - plugin = find_plugin_for_command(cmd); + plugin = find_plugin_for_command(cmd->ld, cmd->json_cmd->name); + if (!plugin) + fatal("No plugin for %s ?", cmd->json_cmd->name); /* Find ID again (We've parsed them before, this should not fail!) */ idtok = json_get_member(buffer, toks, "id"); diff --git a/lightningd/plugin.h b/lightningd/plugin.h index aa89f902b..97ba82e3b 100644 --- a/lightningd/plugin.h +++ b/lightningd/plugin.h @@ -180,6 +180,13 @@ bool plugin_remove(struct plugins *plugins, const char *name); */ void plugin_kill(struct plugin *plugin, char *fmt, ...) PRINTF_FMT(2,3); +/** + * Returns the plugin which registers the command with name {cmd_name} + */ +struct plugin *find_plugin_for_command(struct lightningd *ld, + const char *cmd_name); + + /** * Send the configure message to all plugins. *