Browse Source

daemon/bitcoind: don't eliminate output on non-zero exit status.

Abort if caller wasn't expecting it, otherwise save the result.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
8fe2ba0ab3
  1. 47
      daemon/bitcoind.c

47
daemon/bitcoind.c

@ -50,6 +50,7 @@ struct bitcoin_cli {
struct list_node list; struct list_node list;
struct lightningd_state *dstate; struct lightningd_state *dstate;
int fd; int fd;
int *exitstatus;
pid_t pid; pid_t pid;
char **args; char **args;
char *output; char *output;
@ -108,18 +109,17 @@ static void bcli_finished(struct io_conn *conn, struct bitcoin_cli *bcli)
bcli_args(bcli), bcli_args(bcli),
WTERMSIG(status)); WTERMSIG(status));
if (!bcli->exitstatus) {
if (WEXITSTATUS(status) != 0) { if (WEXITSTATUS(status) != 0) {
log_unusual(dstate->base_log, fatal("%s exited %u: '%.*s'", bcli_args(bcli),
"%s exited %u: '%.*s'", bcli_args(bcli),
WEXITSTATUS(status), WEXITSTATUS(status),
(int)bcli->output_bytes, (int)bcli->output_bytes,
bcli->output); bcli->output);
bcli->output = tal_free(bcli->output); }
bcli->output_bytes = 0;
} else } else
log_debug(dstate->base_log, "reaped %u: %s", *bcli->exitstatus = WEXITSTATUS(status);
ret, bcli_args(bcli));
log_debug(dstate->base_log, "reaped %u: %s", ret, bcli_args(bcli));
dstate->bitcoin_req_running = false; dstate->bitcoin_req_running = false;
bcli->process(bcli); bcli->process(bcli);
@ -153,6 +153,7 @@ static void next_bcli(struct lightningd_state *dstate)
static void static void
start_bitcoin_cli(struct lightningd_state *dstate, start_bitcoin_cli(struct lightningd_state *dstate,
void (*process)(struct bitcoin_cli *), void (*process)(struct bitcoin_cli *),
bool nonzero_exit_ok,
void *cb, void *cb_arg, void *cb, void *cb_arg,
char *cmd, ...) char *cmd, ...)
{ {
@ -163,6 +164,10 @@ start_bitcoin_cli(struct lightningd_state *dstate,
bcli->process = process; bcli->process = process;
bcli->cb = cb; bcli->cb = cb;
bcli->cb_arg = cb_arg; bcli->cb_arg = cb_arg;
if (nonzero_exit_ok)
bcli->exitstatus = tal(bcli, int);
else
bcli->exitstatus = NULL;
va_start(ap, cmd); va_start(ap, cmd);
bcli->args = gather_args(bcli, cmd, ap); bcli->args = gather_args(bcli, cmd, ap);
va_end(ap); va_end(ap);
@ -178,9 +183,6 @@ static void process_estimatefee(struct bitcoin_cli *bcli)
u64 fee_rate; u64 fee_rate;
void (*cb)(struct lightningd_state *, u64, void *) = bcli->cb; void (*cb)(struct lightningd_state *, u64, void *) = bcli->cb;
if (!bcli->output)
fatal("%s failed", bcli_args(bcli));
p = tal_strndup(bcli, bcli->output, bcli->output_bytes); p = tal_strndup(bcli, bcli->output, bcli->output_bytes);
fee = strtod(p, &end); fee = strtod(p, &end);
if (end == p || *end != '\n') if (end == p || *end != '\n')
@ -191,7 +193,7 @@ static void process_estimatefee(struct bitcoin_cli *bcli)
if (fee < 0) { if (fee < 0) {
if (streq(bcli->args[3], "2")) { if (streq(bcli->args[3], "2")) {
start_bitcoin_cli(bcli->dstate, process_estimatefee, start_bitcoin_cli(bcli->dstate, process_estimatefee,
bcli->cb, bcli->cb_arg, false, bcli->cb, bcli->cb_arg,
"estimatefee", "6", NULL); "estimatefee", "6", NULL);
return; return;
} }
@ -214,7 +216,7 @@ void bitcoind_estimate_fee_(struct lightningd_state *dstate,
u64, void *), u64, void *),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, process_estimatefee, cb, arg, start_bitcoin_cli(dstate, process_estimatefee, false, cb, arg,
"estimatefee", "2", NULL); "estimatefee", "2", NULL);
} }
@ -224,8 +226,6 @@ static void process_sendrawrx(struct bitcoin_cli *bcli)
const char *out = (char *)bcli->output; const char *out = (char *)bcli->output;
/* We expect a txid, plus \n */ /* We expect a txid, plus \n */
if (!bcli->output)
fatal("%s failed", bcli_args(bcli));
if (bcli->output_bytes == 0 if (bcli->output_bytes == 0
|| !bitcoin_txid_from_hex(out, bcli->output_bytes-1, &txid)) || !bitcoin_txid_from_hex(out, bcli->output_bytes-1, &txid))
fatal("sendrawtransaction bad hex: %.*s", fatal("sendrawtransaction bad hex: %.*s",
@ -243,7 +243,7 @@ void bitcoind_send_tx(struct lightningd_state *dstate,
u8 *raw = linearize_tx(dstate, tx); u8 *raw = linearize_tx(dstate, tx);
char *hex = tal_hexstr(raw, raw, tal_count(raw)); char *hex = tal_hexstr(raw, raw, tal_count(raw));
start_bitcoin_cli(dstate, process_sendrawrx, NULL, NULL, start_bitcoin_cli(dstate, process_sendrawrx, false, NULL, NULL,
"sendrawtransaction", hex, NULL); "sendrawtransaction", hex, NULL);
tal_free(raw); tal_free(raw);
} }
@ -259,8 +259,6 @@ static void process_chaintips(struct bitcoin_cli *bcli)
void *arg) = bcli->cb; void *arg) = bcli->cb;
log_debug(bcli->dstate->base_log, "Got getchaintips result"); log_debug(bcli->dstate->base_log, "Got getchaintips result");
if (!bcli->output)
fatal("%s failed", bcli_args(bcli));
tokens = json_parse_input(bcli->output, bcli->output_bytes, &valid); tokens = json_parse_input(bcli->output, bcli->output_bytes, &valid);
if (!tokens) if (!tokens)
@ -298,7 +296,7 @@ void bitcoind_get_chaintips_(struct lightningd_state *dstate,
void *arg), void *arg),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, process_chaintips, cb, arg, start_bitcoin_cli(dstate, process_chaintips, false, cb, arg,
"getchaintips", NULL); "getchaintips", NULL);
} }
@ -324,9 +322,6 @@ static void process_rawblock(struct bitcoin_cli *bcli)
void *arg) = bcli->cb; void *arg) = bcli->cb;
/* FIXME: Just get header if we can't get full block. */ /* FIXME: Just get header if we can't get full block. */
if (!bcli->output)
fatal("%s: unknown block?", bcli_args(bcli));
blk = bitcoin_block_from_hex(bcli, bcli->output, bcli->output_bytes); blk = bitcoin_block_from_hex(bcli, bcli->output, bcli->output_bytes);
if (!blk) if (!blk)
fatal("%s: bad block '%.*s'?", fatal("%s: bad block '%.*s'?",
@ -346,7 +341,7 @@ void bitcoind_getrawblock_(struct lightningd_state *dstate,
char hex[hex_str_size(sizeof(*blockid))]; char hex[hex_str_size(sizeof(*blockid))];
bitcoin_blkid_to_hex(blockid, hex, sizeof(hex)); bitcoin_blkid_to_hex(blockid, hex, sizeof(hex));
start_bitcoin_cli(dstate, process_rawblock, cb, arg, start_bitcoin_cli(dstate, process_rawblock, false, cb, arg,
"getblock", hex, "false", NULL); "getblock", hex, "false", NULL);
} }
@ -358,9 +353,6 @@ static void process_getblockcount(struct bitcoin_cli *bcli)
u32 blockcount, u32 blockcount,
void *arg) = bcli->cb; void *arg) = bcli->cb;
if (!bcli->output)
fatal("%s: failed", bcli_args(bcli));
p = tal_strndup(bcli, bcli->output, bcli->output_bytes); p = tal_strndup(bcli, bcli->output, bcli->output_bytes);
blockcount = strtol(p, &end, 10); blockcount = strtol(p, &end, 10);
if (end == p || *end != '\n') if (end == p || *end != '\n')
@ -376,7 +368,7 @@ void bitcoind_getblockcount_(struct lightningd_state *dstate,
void *arg), void *arg),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, process_getblockcount, cb, arg, start_bitcoin_cli(dstate, process_getblockcount, false, cb, arg,
"getblockcount", NULL); "getblockcount", NULL);
} }
@ -387,9 +379,6 @@ static void process_getblockhash(struct bitcoin_cli *bcli)
const struct sha256_double *blkid, const struct sha256_double *blkid,
void *arg) = bcli->cb; void *arg) = bcli->cb;
if (!bcli->output)
fatal("%s: failed", bcli_args(bcli));
if (bcli->output_bytes == 0 if (bcli->output_bytes == 0
|| !bitcoin_blkid_from_hex(bcli->output, bcli->output_bytes-1, || !bitcoin_blkid_from_hex(bcli->output, bcli->output_bytes-1,
&blkid)) { &blkid)) {
@ -410,7 +399,7 @@ void bitcoind_getblockhash_(struct lightningd_state *dstate,
char str[STR_MAX_CHARS(height)]; char str[STR_MAX_CHARS(height)];
sprintf(str, "%u", height); sprintf(str, "%u", height);
start_bitcoin_cli(dstate, process_getblockhash, cb, arg, start_bitcoin_cli(dstate, process_getblockhash, false, cb, arg,
"getblockhash", str, NULL); "getblockhash", str, NULL);
} }

Loading…
Cancel
Save