|
|
@ -535,12 +535,6 @@ struct get_output { |
|
|
|
void *cbarg; |
|
|
|
}; |
|
|
|
|
|
|
|
static void process_get_output(struct bitcoind *bitcoind, const struct bitcoin_tx_output *txout, void *arg) |
|
|
|
{ |
|
|
|
struct get_output *go = arg; |
|
|
|
go->cb(bitcoind, txout, go->cbarg); |
|
|
|
} |
|
|
|
|
|
|
|
static bool process_gettxout(struct bitcoin_cli *bcli) |
|
|
|
{ |
|
|
|
void (*cb)(struct bitcoind *bitcoind, |
|
|
@ -601,127 +595,6 @@ static bool process_gettxout(struct bitcoin_cli *bcli) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* process_getblock -- Retrieve a block from bitcoind |
|
|
|
* |
|
|
|
* Used to resolve a `txoutput` after identifying the blockhash, and |
|
|
|
* before extracting the outpoint from the UTXO. |
|
|
|
*/ |
|
|
|
static bool process_getblock(struct bitcoin_cli *bcli) |
|
|
|
{ |
|
|
|
void (*cb)(struct bitcoind *bitcoind, |
|
|
|
const struct bitcoin_tx_output *output, |
|
|
|
void *arg) = bcli->cb; |
|
|
|
struct get_output *go = bcli->cb_arg; |
|
|
|
void *cbarg = go->cbarg; |
|
|
|
const jsmntok_t *tokens, *txstok, *txidtok; |
|
|
|
struct bitcoin_txid txid; |
|
|
|
bool valid; |
|
|
|
|
|
|
|
tokens = json_parse_input(bcli->output, bcli->output, bcli->output_bytes, |
|
|
|
&valid); |
|
|
|
if (!tokens) { |
|
|
|
/* Most likely we are running on a pruned node, call
|
|
|
|
* the callback with NULL to indicate failure */ |
|
|
|
log_debug(bcli->bitcoind->log, |
|
|
|
"%s: returned invalid block, is this a pruned node?", |
|
|
|
bcli_args(tmpctx, bcli)); |
|
|
|
cb(bcli->bitcoind, NULL, cbarg); |
|
|
|
tal_free(go); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (tokens[0].type != JSMN_OBJECT) |
|
|
|
fatal("%s: gave non-object (%.*s)?", |
|
|
|
bcli_args(tmpctx, bcli), |
|
|
|
(int)bcli->output_bytes, bcli->output); |
|
|
|
|
|
|
|
/* "tx": [
|
|
|
|
"1a7bb0f58a5d235d232deb61d9e2208dabe69848883677abe78e9291a00638e8", |
|
|
|
"56a7e3468c16a4e21a4722370b41f522ad9dd8006c0e4e73c7d1c47f80eced94", |
|
|
|
... |
|
|
|
*/ |
|
|
|
txstok = json_get_member(bcli->output, tokens, "tx"); |
|
|
|
if (!txstok) |
|
|
|
fatal("%s: had no tx member (%.*s)?", |
|
|
|
bcli_args(tmpctx, bcli), |
|
|
|
(int)bcli->output_bytes, bcli->output); |
|
|
|
|
|
|
|
/* Now, this can certainly happen, if txnum too large. */ |
|
|
|
txidtok = json_get_arr(txstok, go->txnum); |
|
|
|
if (!txidtok) { |
|
|
|
log_debug(bcli->bitcoind->log, "%s: no txnum %u", |
|
|
|
bcli_args(tmpctx, bcli), go->txnum); |
|
|
|
cb(bcli->bitcoind, NULL, cbarg); |
|
|
|
tal_free(go); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (!bitcoin_txid_from_hex(bcli->output + txidtok->start, |
|
|
|
txidtok->end - txidtok->start, |
|
|
|
&txid)) |
|
|
|
fatal("%s: had bad txid (%.*s)?", |
|
|
|
bcli_args(tmpctx, bcli), |
|
|
|
json_tok_full_len(txidtok), |
|
|
|
json_tok_full(bcli->output, txidtok)); |
|
|
|
|
|
|
|
go->cb = cb; |
|
|
|
/* Now get the raw tx output. */ |
|
|
|
bitcoind_gettxout(bcli->bitcoind, &txid, go->outnum, process_get_output, go); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static bool process_getblockhash_for_txout(struct bitcoin_cli *bcli) |
|
|
|
{ |
|
|
|
void (*cb)(struct bitcoind *bitcoind, |
|
|
|
const struct bitcoin_tx_output *output, |
|
|
|
void *arg) = bcli->cb; |
|
|
|
struct get_output *go = bcli->cb_arg; |
|
|
|
char *blockhash; |
|
|
|
|
|
|
|
if (*bcli->exitstatus != 0) { |
|
|
|
void *cbarg = go->cbarg; |
|
|
|
log_debug(bcli->bitcoind->log, "%s: invalid blocknum?", |
|
|
|
bcli_args(tmpctx, bcli)); |
|
|
|
tal_free(go); |
|
|
|
cb(bcli->bitcoind, NULL, cbarg); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/* Strip the newline at the end of the previous output */ |
|
|
|
blockhash = tal_strndup(NULL, bcli->output, bcli->output_bytes-1); |
|
|
|
|
|
|
|
start_bitcoin_cli(bcli->bitcoind, NULL, process_getblock, true, |
|
|
|
BITCOIND_LOW_PRIO, |
|
|
|
cb, go, |
|
|
|
"getblock", take(blockhash), NULL); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void bitcoind_getoutput_(struct bitcoind *bitcoind, |
|
|
|
unsigned int blocknum, unsigned int txnum, |
|
|
|
unsigned int outnum, |
|
|
|
void (*cb)(struct bitcoind *bitcoind, |
|
|
|
const struct bitcoin_tx_output *output, |
|
|
|
void *arg), |
|
|
|
void *arg) |
|
|
|
{ |
|
|
|
struct get_output *go = tal(bitcoind, struct get_output); |
|
|
|
go->blocknum = blocknum; |
|
|
|
go->txnum = txnum; |
|
|
|
go->outnum = outnum; |
|
|
|
go->cbarg = arg; |
|
|
|
|
|
|
|
/* We may not have topology ourselves that far back, so ask bitcoind */ |
|
|
|
start_bitcoin_cli(bitcoind, NULL, process_getblockhash_for_txout, |
|
|
|
true, BITCOIND_LOW_PRIO, cb, go, |
|
|
|
"getblockhash", take(tal_fmt(NULL, "%u", blocknum)), |
|
|
|
NULL); |
|
|
|
|
|
|
|
/* Looks like a leak, but we free it in process_getblock */ |
|
|
|
notleak(go); |
|
|
|
} |
|
|
|
|
|
|
|
static bool process_getblockhash(struct bitcoin_cli *bcli) |
|
|
|
{ |
|
|
|
struct bitcoin_blkid blkid; |
|
|
|