Browse Source

lightningd/bitcoind: use json_scan.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
53582a0f81
  1. 136
      lightningd/bitcoind.c

136
lightningd/bitcoind.c

@ -265,31 +265,24 @@ static void sendrawtx_callback(const char *buf, const jsmntok_t *toks,
const jsmntok_t *idtok, const jsmntok_t *idtok,
struct sendrawtx_call *call) struct sendrawtx_call *call)
{ {
const jsmntok_t *resulttok, *successtok, *errtok; const char *errmsg = NULL;
bool success = false; bool success = false;
resulttok = json_get_member(buf, toks, "result"); if (!json_scan(buf, toks, "{result:{success:%}}",
if (!resulttok) JSON_SCAN(json_to_bool, &success))) {
bitcoin_plugin_error(call->bitcoind, buf, toks, bitcoin_plugin_error(call->bitcoind, buf, toks,
"sendrawtransaction", "sendrawtransaction",
"bad 'result' field"); "bad 'result' field");
} else if (!success) {
successtok = json_get_member(buf, resulttok, "success"); if (!json_scan(buf, toks, "{result:{errmsg:%}}",
if (!successtok || !json_to_bool(buf, successtok, &success)) JSON_SCAN_TAL(tmpctx, json_strdup, &errmsg)))
bitcoin_plugin_error(call->bitcoind, buf, toks,
"sendrawtransaction",
"bad 'success' field");
errtok = json_get_member(buf, resulttok, "errmsg");
if (!success && !errtok)
bitcoin_plugin_error(call->bitcoind, buf, toks, bitcoin_plugin_error(call->bitcoind, buf, toks,
"sendrawtransaction", "sendrawtransaction",
"bad 'errmsg' field"); "bad 'errmsg' field");
}
db_begin_transaction(call->bitcoind->ld->wallet->db); db_begin_transaction(call->bitcoind->ld->wallet->db);
call->cb(call->bitcoind, success, call->cb(call->bitcoind, success, errmsg, call->cb_arg);
errtok ? json_strdup(tmpctx, buf, errtok) : NULL,
call->cb_arg);
db_commit_transaction(call->bitcoind->ld->wallet->db); db_commit_transaction(call->bitcoind->ld->wallet->db);
tal_free(call); tal_free(call);
@ -305,9 +298,6 @@ static void sendrawtx_compatv090_callback(const char *buf,
const jsmntok_t *idtok, const jsmntok_t *idtok,
struct sendrawtx_call *call) struct sendrawtx_call *call)
{ {
const jsmntok_t *errtok;
const jsmntok_t *codetok;
errcode_t code;
struct jsonrpc_request *req; struct jsonrpc_request *req;
static bool warned = false; static bool warned = false;
@ -321,19 +311,10 @@ static void sendrawtx_compatv090_callback(const char *buf,
* because it is an old plugin which does not support the * because it is an old plugin which does not support the
* new `allowhighfees` parameter. * new `allowhighfees` parameter.
*/ */
errtok = json_get_member(buf, toks, "error"); if (!json_scan(buf, toks, "{error:{code:"
if (!errtok) stringify(JSONRPC2_INVALID_PARAMS)"}}")) {
goto fallback;
codetok = json_get_member(buf, errtok, "code");
if (!codetok)
goto fallback;
if (!json_to_errcode(buf, codetok, &code))
goto fallback;
if (code != JSONRPC2_INVALID_PARAMS)
goto fallback; goto fallback;
}
/* Possibly it is because `allowhighfees` is not understood /* Possibly it is because `allowhighfees` is not understood
* by the plugin. */ * by the plugin. */
@ -426,42 +407,26 @@ getrawblockbyheight_callback(const char *buf, const jsmntok_t *toks,
const jsmntok_t *idtok, const jsmntok_t *idtok,
struct getrawblockbyheight_call *call) struct getrawblockbyheight_call *call)
{ {
const jsmntok_t *resulttok, *blockhashtok, *blocktok; const char *block_str;
const char *block_str, *blockhash_str;
struct bitcoin_blkid blkid; struct bitcoin_blkid blkid;
struct bitcoin_block *blk; struct bitcoin_block *blk;
resulttok = json_get_member(buf, toks, "result");
if (!resulttok)
bitcoin_plugin_error(call->bitcoind, buf, toks,
"getrawblockbyheight",
"bad 'result' field");
blockhashtok = json_get_member(buf, resulttok, "blockhash");
if (!blockhashtok)
bitcoin_plugin_error(call->bitcoind, buf, toks,
"getrawblockbyheight",
"bad 'blockhash' field");
/* If block hash is `null`, this means not found! Call the callback /* If block hash is `null`, this means not found! Call the callback
* with NULL values. */ * with NULL values. */
if (json_tok_is_null(buf, blockhashtok)) { if (json_scan(buf, toks, "{result:{blockhash:null}}")) {
db_begin_transaction(call->bitcoind->ld->wallet->db); db_begin_transaction(call->bitcoind->ld->wallet->db);
call->cb(call->bitcoind, NULL, NULL, call->cb_arg); call->cb(call->bitcoind, NULL, NULL, call->cb_arg);
db_commit_transaction(call->bitcoind->ld->wallet->db); db_commit_transaction(call->bitcoind->ld->wallet->db);
goto clean; goto clean;
} }
blockhash_str = json_strdup(tmpctx, buf, blockhashtok);
if (!bitcoin_blkid_from_hex(blockhash_str, strlen(blockhash_str), &blkid))
bitcoin_plugin_error(call->bitcoind, buf, toks,
"getrawblockbyheight",
"bad block hash");
blocktok = json_get_member(buf, resulttok, "block"); if (!json_scan(buf, toks, "{result:{blockhash:%,block:%}}",
if (!blocktok) JSON_SCAN(json_to_sha256, &blkid.shad.sha),
JSON_SCAN_TAL(tmpctx, json_strdup, &block_str)))
bitcoin_plugin_error(call->bitcoind, buf, toks, bitcoin_plugin_error(call->bitcoind, buf, toks,
"getrawblockbyheight", "getrawblockbyheight",
"bad 'block' field"); "bad 'result' field");
block_str = json_strdup(tmpctx, buf, blocktok);
blk = bitcoin_block_from_hex(tmpctx, chainparams, block_str, blk = bitcoin_block_from_hex(tmpctx, chainparams, block_str,
strlen(block_str)); strlen(block_str));
if (!blk) if (!blk)
@ -534,39 +499,22 @@ static void getchaininfo_callback(const char *buf, const jsmntok_t *toks,
const jsmntok_t *idtok, const jsmntok_t *idtok,
struct getchaininfo_call *call) struct getchaininfo_call *call)
{ {
const jsmntok_t *resulttok, *chaintok, *headerstok, *blktok, *ibdtok; const char *chain;
u32 headers = 0; u32 headers, blocks;
u32 blocks = 0; bool ibd;
bool ibd = false;
if (!json_scan(buf, toks,
resulttok = json_get_member(buf, toks, "result"); "{result:{chain:%,headercount:%,blockcount:%,ibd:%}}",
if (!resulttok) 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)))
bitcoin_plugin_error(call->bitcoind, buf, toks, "getchaininfo", bitcoin_plugin_error(call->bitcoind, buf, toks, "getchaininfo",
"bad 'result' field"); "bad 'result' field");
chaintok = json_get_member(buf, resulttok, "chain");
if (!chaintok)
bitcoin_plugin_error(call->bitcoind, buf, toks, "getchaininfo",
"bad 'chain' field");
headerstok = json_get_member(buf, resulttok, "headercount");
if (!headerstok || !json_to_number(buf, headerstok, &headers))
bitcoin_plugin_error(call->bitcoind, buf, toks, "getchaininfo",
"bad 'headercount' field");
blktok = json_get_member(buf, resulttok, "blockcount");
if (!blktok || !json_to_number(buf, blktok, &blocks))
bitcoin_plugin_error(call->bitcoind, buf, toks, "getchaininfo",
"bad 'blockcount' field");
ibdtok = json_get_member(buf, resulttok, "ibd");
if (!ibdtok || !json_to_bool(buf, ibdtok, &ibd))
bitcoin_plugin_error(call->bitcoind, buf, toks, "getchaininfo",
"bad 'ibd' field");
db_begin_transaction(call->bitcoind->ld->wallet->db); db_begin_transaction(call->bitcoind->ld->wallet->db);
call->cb(call->bitcoind, json_strdup(tmpctx, buf, chaintok), headers, call->cb(call->bitcoind, chain, headers, blocks, ibd,
blocks, ibd, call->first_call, call->cb_arg); call->first_call, call->cb_arg);
db_commit_transaction(call->bitcoind->ld->wallet->db); db_commit_transaction(call->bitcoind->ld->wallet->db);
tal_free(call); tal_free(call);
@ -622,33 +570,21 @@ static void getutxout_callback(const char *buf, const jsmntok_t *toks,
const jsmntok_t *idtok, const jsmntok_t *idtok,
struct getutxout_call *call) struct getutxout_call *call)
{ {
const jsmntok_t *resulttok, *amounttok, *scripttok;
struct bitcoin_tx_output txout; struct bitcoin_tx_output txout;
resulttok = json_get_member(buf, toks, "result"); if (json_scan(buf, toks, "{result:{script:null}}")) {
if (!resulttok)
bitcoin_plugin_error(call->bitcoind, buf, toks, "getutxout",
"bad 'result' field");
scripttok = json_get_member(buf, resulttok, "script");
if (!scripttok)
bitcoin_plugin_error(call->bitcoind, buf, toks, "getutxout",
"bad 'script' field");
if (json_tok_is_null(buf, scripttok)) {
db_begin_transaction(call->bitcoind->ld->wallet->db); db_begin_transaction(call->bitcoind->ld->wallet->db);
call->cb(call->bitcoind, NULL, call->cb_arg); call->cb(call->bitcoind, NULL, call->cb_arg);
db_commit_transaction(call->bitcoind->ld->wallet->db); db_commit_transaction(call->bitcoind->ld->wallet->db);
goto clean; goto clean;
} }
txout.script = json_tok_bin_from_hex(tmpctx, buf, scripttok);
amounttok = json_get_member(buf, resulttok, "amount"); if (!json_scan(buf, toks, "{result:{script:%,amount:%}}",
if (!amounttok) JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex,
&txout.script),
JSON_SCAN(json_to_sat, &txout.amount)))
bitcoin_plugin_error(call->bitcoind, buf, toks, "getutxout", bitcoin_plugin_error(call->bitcoind, buf, toks, "getutxout",
"bad 'amount' field"); "bad 'result' field");
if (!json_to_sat(buf, amounttok, &txout.amount))
bitcoin_plugin_error(call->bitcoind, buf, toks, "getutxout",
"bad sats amount");
db_begin_transaction(call->bitcoind->ld->wallet->db); db_begin_transaction(call->bitcoind->ld->wallet->db);
call->cb(call->bitcoind, &txout, call->cb_arg); call->cb(call->bitcoind, &txout, call->cb_arg);

Loading…
Cancel
Save