From 130bf20516be815acc5034ba84b9c106ac6274a9 Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Sun, 28 Jul 2019 01:58:27 +0800 Subject: [PATCH] lightningd: check bitcoind version when `setup_topology` --- lightningd/bitcoind.c | 60 ++++++++++++++++++++++++++++++++++++++ lightningd/bitcoind.h | 2 ++ lightningd/chaintopology.c | 2 ++ 3 files changed, 64 insertions(+) diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index 5b8d071b5..09340224a 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -783,6 +783,66 @@ void bitcoind_gettxout(struct bitcoind *bitcoind, NULL); } +static bool extract_numeric_version(struct bitcoin_cli *bcli, + const char *output, size_t output_bytes, + u64 *version) +{ + const jsmntok_t *tokens, *versiontok; + bool valid; + + tokens = json_parse_input(output, output, output_bytes, &valid); + if (!tokens) + fatal("%s: %s response", + bcli_args(tmpctx, bcli), + valid ? "partial" : "invalid"); + + if (tokens[0].type != JSMN_OBJECT) { + log_unusual(bcli->bitcoind->log, + "%s: gave non-object (%.*s)?", + bcli_args(tmpctx, bcli), + (int)output_bytes, output); + return false; + } + + versiontok = json_get_member(output, tokens, "version"); + if (!versiontok) + return false; + + return json_to_u64(output, versiontok, version); +} + +static bool process_getclientversion(struct bitcoin_cli *bcli) +{ + u64 version; + u64 min_version = bcli->bitcoind->chainparams->cli_min_supported_version; + + if (!extract_numeric_version(bcli, bcli->output, + bcli->output_bytes, + &version)) { + fatal("%s: Unable to getclientversion (%.*s)", + bcli_args(tmpctx, bcli), + (int)bcli->output_bytes, + bcli->output); + } + + if (version < min_version) + fatal("Unsupported bitcoind version? bitcoind version: %"PRIu64"," + " supported minimum version: %"PRIu64"", + version, min_version); + + return true; +} + +void bitcoind_getclientversion(struct bitcoind *bitcoind) +{ + /* `getnetworkinfo` was added in v0.14.0. The older version would + * return non-zero exitstatus. */ + start_bitcoin_cli(bitcoind, NULL, process_getclientversion, false, + BITCOIND_HIGH_PRIO, + NULL, NULL, + "getnetworkinfo", NULL); +} + static void destroy_bitcoind(struct bitcoind *bitcoind) { /* Suppresses the callbacks from bcli_finished as we free conns. */ diff --git a/lightningd/bitcoind.h b/lightningd/bitcoind.h index 0e395f93f..53fa82459 100644 --- a/lightningd/bitcoind.h +++ b/lightningd/bitcoind.h @@ -168,4 +168,6 @@ void bitcoind_gettxout(struct bitcoind *bitcoind, void *arg), void *arg); +void bitcoind_getclientversion(struct bitcoind *bitcoind); + #endif /* LIGHTNING_LIGHTNINGD_BITCOIND_H */ diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 42ef7a782..9ca8b7f97 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -912,6 +912,8 @@ void setup_topology(struct chain_topology *topo, /* Make sure bitcoind is started, and ready */ wait_for_bitcoind(topo->bitcoind); + bitcoind_getclientversion(topo->bitcoind); + bitcoind_getblockcount(topo->bitcoind, get_init_blockhash, topo); tal_add_destructor(topo, destroy_chain_topology);