diff --git a/doc/PLUGINS.md b/doc/PLUGINS.md index 99c356581600..c74072b8a706 100644 --- a/doc/PLUGINS.md +++ b/doc/PLUGINS.md @@ -1716,7 +1716,8 @@ data. Each plugin must follow the below specification for `lightningd` to operat ### `getchaininfo` Called at startup, it's used to check the network `lightningd` is operating on and to -get the sync status of the backend. +get the sync status of the backend. Optionally, the plugins can use `last_height` to +make sure that the Bitcoin backend is not behind core lightning. The plugin must respond to `getchaininfo` with the following fields: - `chain` (string), the network name as introduced in bip70 diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index e4bbb1eba25a..a9f76ac86c10 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -578,6 +578,7 @@ static void getchaininfo_callback(const char *buf, const jsmntok_t *toks, void bitcoind_getchaininfo_(struct bitcoind *bitcoind, const bool first_call, + const u32 height, void (*cb)(struct bitcoind *bitcoind, const char *chain, u32 headercount, @@ -598,6 +599,7 @@ void bitcoind_getchaininfo_(struct bitcoind *bitcoind, req = jsonrpc_request_start(bitcoind, "getchaininfo", NULL, true, bitcoind->log, NULL, getchaininfo_callback, call); + json_add_u32(req->stream, "last_height", height); jsonrpc_request_end(req); bitcoin_plugin_send(bitcoind, req); } diff --git a/lightningd/bitcoind.h b/lightningd/bitcoind.h index 0986d438abfb..b58ed06d4f84 100644 --- a/lightningd/bitcoind.h +++ b/lightningd/bitcoind.h @@ -95,6 +95,7 @@ void bitcoind_getfilteredblock_(struct bitcoind *bitcoind, u32 height, void bitcoind_getchaininfo_(struct bitcoind *bitcoind, const bool first_call, + const u32 height, void (*cb)(struct bitcoind *bitcoind, const char *chain, u32 headercount, @@ -102,8 +103,8 @@ void bitcoind_getchaininfo_(struct bitcoind *bitcoind, const bool ibd, const bool first_call, void *), void *cb_arg); -#define bitcoind_getchaininfo(bitcoind_, first_call_, cb, arg) \ - bitcoind_getchaininfo_((bitcoind_), (first_call_), \ +#define bitcoind_getchaininfo(bitcoind_, first_call_, height_, cb, arg) \ + bitcoind_getchaininfo_((bitcoind_), (first_call_), (height_), \ typesafe_cb_preargs(void, void *, \ (cb), (arg), \ struct bitcoind *, \ diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 4b659589dea8..ca2f54fa545d 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -1287,7 +1287,7 @@ static void retry_check_chain(struct chain_topology *topo) topo->bitcoind->checkchain_timer = NULL; if (topo->stopping) return; - bitcoind_getchaininfo(topo->bitcoind, false, check_chain, topo); + bitcoind_getchaininfo(topo->bitcoind, false, topo->max_blockheight, check_chain, topo); } void setup_topology(struct chain_topology *topo, @@ -1306,7 +1306,7 @@ void setup_topology(struct chain_topology *topo, /* Sanity checks, then topology initialization. */ topo->bitcoind->checkchain_timer = NULL; - bitcoind_getchaininfo(topo->bitcoind, true, check_chain, topo); + bitcoind_getchaininfo(topo->bitcoind, true, topo->max_blockheight, check_chain, topo); tal_add_destructor(topo, destroy_chain_topology); diff --git a/plugins/bcli.c b/plugins/bcli.c index f5fef9029a68..f4816976107b 100644 --- a/plugins/bcli.c +++ b/plugins/bcli.c @@ -656,7 +656,15 @@ static struct command_result *getchaininfo(struct command *cmd, const char *buf UNUSED, const jsmntok_t *toks UNUSED) { - if (!param(cmd, buf, toks, NULL)) + /* FIXME(vincenzopalazzo): Inside the JSON request, + * we have the current height known from Core Lightning. Therefore, + * we can attempt to prevent a crash if the 'getchaininfo' function returns + * a lower height than the one we already know, by waiting for a short period. + * However, I currently don't have a better idea on how to handle this situation. */ + u32 *height UNUSED; + if (!param(cmd, buf, toks, + p_req("last_height", param_number, &height), + NULL)) return command_param_failed(); start_bitcoin_cli(NULL, cmd, process_getblockchaininfo, false, diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 593a4e217391..95a81042fd7b 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1759,7 +1759,7 @@ def test_bcli(node_factory, bitcoind, chainparams): assert 'feerate_floor' in estimates assert [f['blocks'] for f in estimates['feerates']] == [2, 6, 12, 100] - resp = l1.rpc.call("getchaininfo") + resp = l1.rpc.call("getchaininfo", {"last_height": 0}) assert resp["chain"] == chainparams['name'] for field in ["headercount", "blockcount", "ibd"]: assert field in resp