plugins/bcli: convert to json_scan.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-01-06 16:11:19 +10:30 committed by Christian Decker
parent a5befb0072
commit 35e8949df3

View File

@ -323,7 +323,7 @@ static struct command_result *command_err_bcli_badjson(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;
struct json_stream *response;
struct bitcoin_tx_output output;
@ -343,35 +343,13 @@ static struct command_result *process_getutxout(struct bitcoin_cli *bcli)
return command_err_bcli_badjson(bcli, "cannot parse");
}
if (tokens[0].type != JSMN_OBJECT) {
return command_err_bcli_badjson(bcli, "non-object");
}
valuetok = json_get_member(bcli->output, tokens, "value");
if (!valuetok) {
return command_err_bcli_badjson(bcli, "no value member");
}
if (!json_to_bitcoin_amount(bcli->output, valuetok, &output.amount.satoshis)) {/* Raw: talking to bitcoind */
return command_err_bcli_badjson(bcli, "bad value member");
}
scriptpubkeytok = json_get_member(bcli->output, tokens, "scriptPubKey");
if (!scriptpubkeytok) {
return command_err_bcli_badjson(bcli, "no scriptPubkey member");
}
hextok = json_get_member(bcli->output, scriptpubkeytok, "hex");
if (!hextok) {
return command_err_bcli_badjson(bcli,
"no scriptPubkey.hex member");
}
output.script = tal_hexdata(bcli, bcli->output + hextok->start,
hextok->end - hextok->start);
if (!output.script) {
return command_err_bcli_badjson(bcli,
"scriptPubkey.hex invalid hex");
if (!json_scan(bcli->output, tokens,
"{value:%,scriptPubKey:{hex:%}}",
JSON_SCAN(json_to_bitcoin_amount,
&output.amount.satoshis), /* Raw: bitcoind */
JSON_SCAN_TAL(bcli, json_tok_bin_from_hex,
&output.script))) {
return command_err_bcli_badjson(bcli, "cannot scan");
}
response = jsonrpc_stream_success(bcli->cmd);
@ -383,10 +361,11 @@ static struct command_result *process_getutxout(struct bitcoin_cli *bcli)
static struct command_result *process_getblockchaininfo(struct bitcoin_cli *bcli)
{
const jsmntok_t *tokens, *chaintok, *headerstok, *blockstok, *ibdtok;
const jsmntok_t *tokens;
struct json_stream *response;
bool ibd;
u32 headers, blocks;
const char *chain;
tokens = json_parse_simple(bcli->output,
bcli->output, bcli->output_bytes);
@ -394,36 +373,17 @@ static struct command_result *process_getblockchaininfo(struct bitcoin_cli *bcli
return command_err_bcli_badjson(bcli, "cannot parse");
}
if (tokens[0].type != JSMN_OBJECT) {
return command_err_bcli_badjson(bcli, "non-object");
}
chaintok = json_get_member(bcli->output, tokens, "chain");
if (!chaintok) {
return command_err_bcli_badjson(bcli, "missing chain member");
}
headerstok = json_get_member(bcli->output, tokens, "headers");
if (!headerstok || !json_to_number(bcli->output, headerstok, &headers)) {
return command_err_bcli_badjson(bcli,
"missing/bad headers member");
}
blockstok = json_get_member(bcli->output, tokens, "blocks");
if (!blockstok || !json_to_number(bcli->output, blockstok, &blocks)) {
return command_err_bcli_badjson(bcli,
"missing/bad blocks member");
}
ibdtok = json_get_member(bcli->output, tokens, "initialblockdownload");
if (!ibdtok || !json_to_bool(bcli->output, ibdtok, &ibd)) {
return command_err_bcli_badjson(bcli,
"missing/bad initialblockdownload member");
if (!json_scan(bcli->output, tokens,
"{chain:%,headers:%,blocks:%,initialblockdownload:%}",
JSON_SCAN_TAL(tmpctx, json_strdup, &chain),
JSON_SCAN(json_to_number, &headers),
JSON_SCAN(json_to_number, &blocks),
JSON_SCAN(json_to_bool, &ibd))) {
return command_err_bcli_badjson(bcli, "cannot scan");
}
response = jsonrpc_stream_success(bcli->cmd);
json_add_string(response, "chain",
json_strdup(response, bcli->output, chaintok));
json_add_string(response, "chain", chain);
json_add_u32(response, "headercount", headers);
json_add_u32(response, "blockcount", blocks);
json_add_bool(response, "ibd", ibd);
@ -457,7 +417,7 @@ estimatefees_null_response(struct bitcoin_cli *bcli)
static struct command_result *
estimatefees_parse_feerate(struct bitcoin_cli *bcli, u64 *feerate)
{
const jsmntok_t *tokens, *feeratetok = NULL;
const jsmntok_t *tokens;
tokens = json_parse_simple(bcli->output,
bcli->output, bcli->output_bytes);
@ -465,18 +425,15 @@ estimatefees_parse_feerate(struct bitcoin_cli *bcli, u64 *feerate)
return command_err_bcli_badjson(bcli, "cannot parse");
}
if (tokens[0].type != JSMN_OBJECT) {
return command_err_bcli_badjson(bcli, "non-object");
}
feeratetok = json_get_member(bcli->output, tokens, "feerate");
if (feeratetok &&
!json_to_bitcoin_amount(bcli->output, feeratetok, feerate)) {
return command_err_bcli_badjson(bcli, "bad feerate");
} else if (!feeratetok)
if (!json_scan(bcli->output, tokens, "{feerate:%}",
JSON_SCAN(json_to_bitcoin_amount, feerate))) {
/* Paranoia: if it had a feerate, but was malformed: */
if (json_get_member(bcli->output, tokens, "feerate"))
return command_err_bcli_badjson(bcli, "cannot scan");
/* We return null if estimation failed, and bitcoin-cli will
* exit with 0 but no feerate field on failure. */
return estimatefees_null_response(bcli);
}
return NULL;
}
@ -822,7 +779,7 @@ static void bitcoind_failure(struct plugin *p, const char *error_message)
/* Do some sanity checks on bitcoind based on the output of `getnetworkinfo`. */
static void parse_getnetworkinfo_result(struct plugin *p, const char *buf)
{
const jsmntok_t *result, *versiontok, *relaytok;
const jsmntok_t *result;
bool tx_relay;
u32 min_version = 160000;
@ -833,14 +790,10 @@ static void parse_getnetworkinfo_result(struct plugin *p, const char *buf)
gather_args(bitcoind, "getnetworkinfo", NULL), buf);
/* Check that we have a fully-featured `estimatesmartfee`. */
versiontok = json_get_member(buf, result, "version");
if (!versiontok)
plugin_err(p, "No 'version' in '%s' ? Got '%s'. Can not"
" continue without proceeding to sanity checks.",
gather_args(bitcoind, "getnetworkinfo", NULL), buf);
if (!json_to_u32(buf, versiontok, &bitcoind->version))
plugin_err(p, "Invalid 'version' in '%s' ? Got '%s'. Can not"
if (!json_scan(buf, result, "{version:%,localrelay:%}",
JSON_SCAN(json_to_u32, &bitcoind->version),
JSON_SCAN(json_to_bool, &tx_relay)))
plugin_err(p, "No 'version' or localrelay in '%s' ? Got '%s'. Can not"
" continue without proceeding to sanity checks.",
gather_args(bitcoind, "getnetworkinfo", NULL), buf);
@ -850,12 +803,6 @@ static void parse_getnetworkinfo_result(struct plugin *p, const char *buf)
/* We don't support 'blocksonly', as we rely on transaction relay for fee
* estimates. */
relaytok = json_get_member(buf, result, "localrelay");
if (!relaytok || !json_to_bool(buf, relaytok, &tx_relay))
plugin_err(p, "No 'localrelay' in '%s' ? Got '%s'. Can not"
" continue without proceeding to sanity checks.",
gather_args(bitcoind, "getnetworkinfo", NULL), buf);
if (!tx_relay)
plugin_err(p, "The 'blocksonly' mode of bitcoind, or any option "
"deactivating transaction relay is not supported.");