Get a raw block given its height. * Calls `getblockhash` then `getblock` to retrieve it from bitcoin_cli. * Will return early with null fields if block isn't known (yet). */
| 345 | * Will return early with null fields if block isn't known (yet). |
| 346 | */ |
| 347 | static struct command_result *getrawblockbyheight(struct command *cmd, |
| 348 | const char *buf, |
| 349 | const jsmntok_t *toks) |
| 350 | { |
| 351 | struct bcli_result *res; |
| 352 | struct json_stream *response; |
| 353 | const char *block_hash; |
| 354 | u32 *height; |
| 355 | struct timemono first_error_time; |
| 356 | bool first_error = true; |
| 357 | int *peers = NULL; |
| 358 | |
| 359 | if (!param(cmd, buf, toks, |
| 360 | p_req("height", param_number, &height), |
| 361 | NULL)) |
| 362 | return command_param_failed(); |
| 363 | |
| 364 | res = run_bitcoin_cli(cmd, cmd->plugin, "getblockhash", |
| 365 | tal_fmt(tmpctx, "%u", *height), NULL); |
| 366 | |
| 367 | if (res->exitstatus != 0) { |
| 368 | return getrawblockbyheight_notfound(cmd); |
| 369 | } |
| 370 | |
| 371 | strip_trailing_whitespace(res->output, res->output_len); |
| 372 | if (strlen(res->output) != BLOCK_HASH_HEX_LEN) |
| 373 | return command_err(cmd, res, "bad JSON: bad blockhash"); |
| 374 | |
| 375 | block_hash = tal_strdup(cmd, res->output); |
| 376 | |
| 377 | for (;;) { |
| 378 | res = run_bitcoin_cli(cmd, cmd->plugin, "getblock", |
| 379 | block_hash, "0", NULL); |
| 380 | |
| 381 | if (res->exitstatus == 0) { |
| 382 | strip_trailing_whitespace(res->output, res->output_len); |
| 383 | response = jsonrpc_stream_success(cmd); |
| 384 | json_add_string(response, "blockhash", block_hash); |
| 385 | json_add_string(response, "block", res->output); |
| 386 | return command_finished(cmd, response); |
| 387 | } |
| 388 | |
| 389 | plugin_log(cmd->plugin, LOG_DBG, |
| 390 | "failed to fetch block %s from the bitcoin backend (maybe pruned).", |
| 391 | block_hash); |
| 392 | |
| 393 | if (first_error) { |
| 394 | first_error_time = time_mono(); |
| 395 | first_error = false; |
| 396 | } |
| 397 | |
| 398 | struct timerel elapsed = timemono_between(time_mono(), first_error_time); |
| 399 | if (time_greater(elapsed, time_from_sec(bitcoind->retry_timeout))) { |
| 400 | return command_done_err(cmd, BCLI_ERROR, |
| 401 | tal_fmt(cmd, "getblock %s timed out after %"PRIu64" seconds", |
| 402 | block_hash, bitcoind->retry_timeout), NULL); |
| 403 | } |
| 404 |
nothing calls this directly
no test coverage detected