mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
plugins/bcli: use simplified parser, unify bad JSON paths.
They should all show the complete JSON, so unify them. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
126
plugins/bcli.c
126
plugins/bcli.c
@@ -312,13 +312,20 @@ start_bitcoin_cli(const tal_t *ctx,
|
|||||||
next_bcli(bcli->prio);
|
next_bcli(bcli->prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct command_result *command_err_bcli_badjson(struct bitcoin_cli *bcli,
|
||||||
|
const char *errmsg)
|
||||||
|
{
|
||||||
|
char *err = tal_fmt(bcli, "%s: bad JSON: %s (%.*s)",
|
||||||
|
bcli_args(bcli), errmsg,
|
||||||
|
(int)bcli->output_bytes, bcli->output);
|
||||||
|
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static struct command_result *process_getutxout(struct bitcoin_cli *bcli)
|
static struct command_result *process_getutxout(struct bitcoin_cli *bcli)
|
||||||
{
|
{
|
||||||
const jsmntok_t *tokens, *valuetok, *scriptpubkeytok, *hextok;
|
const jsmntok_t *tokens, *valuetok, *scriptpubkeytok, *hextok;
|
||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
bool valid;
|
|
||||||
struct bitcoin_tx_output output;
|
struct bitcoin_tx_output output;
|
||||||
char *err;
|
|
||||||
|
|
||||||
/* As of at least v0.15.1.0, bitcoind returns "success" but an empty
|
/* As of at least v0.15.1.0, bitcoind returns "success" but an empty
|
||||||
string on a spent txout. */
|
string on a spent txout. */
|
||||||
@@ -330,59 +337,41 @@ static struct command_result *process_getutxout(struct bitcoin_cli *bcli)
|
|||||||
return command_finished(bcli->cmd, response);
|
return command_finished(bcli->cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = json_parse_input(bcli->output, bcli->output,
|
tokens = json_parse_simple(bcli->output, bcli->output,
|
||||||
bcli->output_bytes, &valid);
|
bcli->output_bytes);
|
||||||
if (!tokens) {
|
if (!tokens) {
|
||||||
err = tal_fmt(bcli, "%s: %s response", bcli_args(bcli),
|
return command_err_bcli_badjson(bcli, "cannot parse");
|
||||||
valid ? "partial" : "invalid");
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens[0].type != JSMN_OBJECT) {
|
if (tokens[0].type != JSMN_OBJECT) {
|
||||||
err = tal_fmt(bcli, "%s: gave non-object (%.*s)?",
|
return command_err_bcli_badjson(bcli, "non-object");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
valuetok = json_get_member(bcli->output, tokens, "value");
|
valuetok = json_get_member(bcli->output, tokens, "value");
|
||||||
if (!valuetok) {
|
if (!valuetok) {
|
||||||
err = tal_fmt(bcli,"%s: had no value member (%.*s)?",
|
return command_err_bcli_badjson(bcli, "no value member");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_to_bitcoin_amount(bcli->output, valuetok, &output.amount.satoshis)) {/* Raw: talking to bitcoind */
|
if (!json_to_bitcoin_amount(bcli->output, valuetok, &output.amount.satoshis)) {/* Raw: talking to bitcoind */
|
||||||
err = tal_fmt(bcli, "%s: had bad value (%.*s)?",
|
return command_err_bcli_badjson(bcli, "bad value member");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptpubkeytok = json_get_member(bcli->output, tokens, "scriptPubKey");
|
scriptpubkeytok = json_get_member(bcli->output, tokens, "scriptPubKey");
|
||||||
if (!scriptpubkeytok) {
|
if (!scriptpubkeytok) {
|
||||||
err = tal_fmt(bcli, "%s: had no scriptPubKey member (%.*s)?",
|
return command_err_bcli_badjson(bcli, "no scriptPubkey member");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hextok = json_get_member(bcli->output, scriptpubkeytok, "hex");
|
hextok = json_get_member(bcli->output, scriptpubkeytok, "hex");
|
||||||
if (!hextok) {
|
if (!hextok) {
|
||||||
err = tal_fmt(bcli, "%s: had no scriptPubKey->hex member (%.*s)?",
|
return command_err_bcli_badjson(bcli,
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
"no scriptPubkey.hex member");
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output.script = tal_hexdata(bcli, bcli->output + hextok->start,
|
output.script = tal_hexdata(bcli, bcli->output + hextok->start,
|
||||||
hextok->end - hextok->start);
|
hextok->end - hextok->start);
|
||||||
if (!output.script) {
|
if (!output.script) {
|
||||||
err = tal_fmt(bcli, "%s: scriptPubKey->hex invalid hex (%.*s)?",
|
return command_err_bcli_badjson(bcli,
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
"scriptPubkey.hex invalid hex");
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = jsonrpc_stream_success(bcli->cmd);
|
response = jsonrpc_stream_success(bcli->cmd);
|
||||||
@@ -396,56 +385,40 @@ static struct command_result *process_getblockchaininfo(struct bitcoin_cli *bcli
|
|||||||
{
|
{
|
||||||
const jsmntok_t *tokens, *chaintok, *headerstok, *blockstok, *ibdtok;
|
const jsmntok_t *tokens, *chaintok, *headerstok, *blockstok, *ibdtok;
|
||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
bool valid, ibd;
|
bool ibd;
|
||||||
u32 headers, blocks;
|
u32 headers, blocks;
|
||||||
char *err;
|
|
||||||
|
|
||||||
tokens = json_parse_input(bcli, bcli->output, bcli->output_bytes,
|
tokens = json_parse_simple(bcli->output,
|
||||||
&valid);
|
bcli->output, bcli->output_bytes);
|
||||||
if (!tokens) {
|
if (!tokens) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: %s response (%.*s)",
|
return command_err_bcli_badjson(bcli, "cannot parse");
|
||||||
bcli_args(bcli), valid ? "partial" : "invalid",
|
|
||||||
(int)bcli->output_bytes, bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens[0].type != JSMN_OBJECT) {
|
if (tokens[0].type != JSMN_OBJECT) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: gave non-object (%.*s)",
|
return command_err_bcli_badjson(bcli, "non-object");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chaintok = json_get_member(bcli->output, tokens, "chain");
|
chaintok = json_get_member(bcli->output, tokens, "chain");
|
||||||
if (!chaintok) {
|
if (!chaintok) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: bad 'chain' field (%.*s)",
|
return command_err_bcli_badjson(bcli, "missing chain member");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
headerstok = json_get_member(bcli->output, tokens, "headers");
|
headerstok = json_get_member(bcli->output, tokens, "headers");
|
||||||
if (!headerstok || !json_to_number(bcli->output, headerstok, &headers)) {
|
if (!headerstok || !json_to_number(bcli->output, headerstok, &headers)) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: bad 'headers' field (%.*s)",
|
return command_err_bcli_badjson(bcli,
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
"missing/bad headers member");
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blockstok = json_get_member(bcli->output, tokens, "blocks");
|
blockstok = json_get_member(bcli->output, tokens, "blocks");
|
||||||
if (!blockstok || !json_to_number(bcli->output, blockstok, &blocks)) {
|
if (!blockstok || !json_to_number(bcli->output, blockstok, &blocks)) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: bad 'blocks' field (%.*s)",
|
return command_err_bcli_badjson(bcli,
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
"missing/bad blocks member");
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ibdtok = json_get_member(bcli->output, tokens, "initialblockdownload");
|
ibdtok = json_get_member(bcli->output, tokens, "initialblockdownload");
|
||||||
if (!ibdtok || !json_to_bool(bcli->output, ibdtok, &ibd)) {
|
if (!ibdtok || !json_to_bool(bcli->output, ibdtok, &ibd)) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: bad 'initialblockdownload' field (%.*s)",
|
return command_err_bcli_badjson(bcli,
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
"missing/bad initialblockdownload member");
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = jsonrpc_stream_success(bcli->cmd);
|
response = jsonrpc_stream_success(bcli->cmd);
|
||||||
@@ -485,32 +458,21 @@ static struct command_result *
|
|||||||
estimatefees_parse_feerate(struct bitcoin_cli *bcli, u64 *feerate)
|
estimatefees_parse_feerate(struct bitcoin_cli *bcli, u64 *feerate)
|
||||||
{
|
{
|
||||||
const jsmntok_t *tokens, *feeratetok = NULL;
|
const jsmntok_t *tokens, *feeratetok = NULL;
|
||||||
bool valid;
|
|
||||||
char *err;
|
|
||||||
|
|
||||||
tokens = json_parse_input(bcli->output, bcli->output,
|
tokens = json_parse_simple(bcli->output,
|
||||||
(int)bcli->output_bytes, &valid);
|
bcli->output, bcli->output_bytes);
|
||||||
if (!tokens) {
|
if (!tokens) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: %s response (%.*s)",
|
return command_err_bcli_badjson(bcli, "cannot parse");
|
||||||
bcli_args(bcli), valid ? "partial" : "invalid",
|
|
||||||
(int)bcli->output_bytes, bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens[0].type != JSMN_OBJECT) {
|
if (tokens[0].type != JSMN_OBJECT) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: gave non-object (%.*s)",
|
return command_err_bcli_badjson(bcli, "non-object");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
feeratetok = json_get_member(bcli->output, tokens, "feerate");
|
feeratetok = json_get_member(bcli->output, tokens, "feerate");
|
||||||
if (feeratetok &&
|
if (feeratetok &&
|
||||||
!json_to_bitcoin_amount(bcli->output, feeratetok, feerate)) {
|
!json_to_bitcoin_amount(bcli->output, feeratetok, feerate)) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: bad 'feerate' field (%.*s)",
|
return command_err_bcli_badjson(bcli, "bad feerate");
|
||||||
bcli_args(bcli), (int)bcli->output_bytes,
|
|
||||||
bcli->output);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
} else if (!feeratetok)
|
} else if (!feeratetok)
|
||||||
/* We return null if estimation failed, and bitcoin-cli will
|
/* We return null if estimation failed, and bitcoin-cli will
|
||||||
* exit with 0 but no feerate field on failure. */
|
* exit with 0 but no feerate field on failure. */
|
||||||
@@ -681,7 +643,7 @@ getrawblockbyheight_notfound(struct bitcoin_cli *bcli)
|
|||||||
|
|
||||||
static struct command_result *process_getblockhash(struct bitcoin_cli *bcli)
|
static struct command_result *process_getblockhash(struct bitcoin_cli *bcli)
|
||||||
{
|
{
|
||||||
const char *err, **params;
|
const char **params;
|
||||||
struct getrawblock_stash *stash = bcli->stash;
|
struct getrawblock_stash *stash = bcli->stash;
|
||||||
|
|
||||||
/* If it failed with error 8, give an empty response. */
|
/* If it failed with error 8, give an empty response. */
|
||||||
@@ -696,9 +658,7 @@ static struct command_result *process_getblockhash(struct bitcoin_cli *bcli)
|
|||||||
stash->block_hash = tal_strndup(stash, bcli->output,
|
stash->block_hash = tal_strndup(stash, bcli->output,
|
||||||
bcli->output_bytes-1);
|
bcli->output_bytes-1);
|
||||||
if (!stash->block_hash || strlen(stash->block_hash) != 64) {
|
if (!stash->block_hash || strlen(stash->block_hash) != 64) {
|
||||||
err = tal_fmt(bcli->cmd, "%s: bad blockhash '%s'",
|
return command_err_bcli_badjson(bcli, "bad blockhash");
|
||||||
bcli_args(bcli), stash->block_hash);
|
|
||||||
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
params = tal_arr(bcli->cmd, const char *, 2);
|
params = tal_arr(bcli->cmd, const char *, 2);
|
||||||
@@ -841,13 +801,11 @@ static void bitcoind_failure(struct plugin *p, const char *error_message)
|
|||||||
static void parse_getnetworkinfo_result(struct plugin *p, const char *buf)
|
static void parse_getnetworkinfo_result(struct plugin *p, const char *buf)
|
||||||
{
|
{
|
||||||
const jsmntok_t *result, *versiontok, *relaytok;
|
const jsmntok_t *result, *versiontok, *relaytok;
|
||||||
bool valid, tx_relay;
|
bool tx_relay;
|
||||||
u32 min_version = 160000;
|
u32 min_version = 160000;
|
||||||
|
|
||||||
result = json_parse_input(NULL,
|
result = json_parse_simple(NULL, buf, strlen(buf));
|
||||||
buf, strlen(buf),
|
if (!result)
|
||||||
&valid);
|
|
||||||
if (!result || !valid)
|
|
||||||
plugin_err(p, "Invalid response to '%s': '%s'. Can not "
|
plugin_err(p, "Invalid response to '%s': '%s'. Can not "
|
||||||
"continue without proceeding to sanity checks.",
|
"continue without proceeding to sanity checks.",
|
||||||
gather_args(bitcoind, "getnetworkinfo", NULL), buf);
|
gather_args(bitcoind, "getnetworkinfo", NULL), buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user