MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / rest_block

Function rest_block

src/rest.cpp:390–470  ·  view source on GitHub ↗

* This handler is used by multiple HTTP endpoints: * - `/block/` via `rest_block_extended()` * - `/block/notxdetails/` via `rest_block_notxdetails()` * - `/blockpart/` via `rest_block_part()` (doesn't support JSON response, so `tx_verbosity` is unset) */

Source from the content-addressed store, hash-verified

388 * - `/blockpart/` via `rest_block_part()` (doesn't support JSON response, so `tx_verbosity` is unset)
389 */
390static bool rest_block(const std::any& context,
391 HTTPRequest* req,
392 const std::string& uri_part,
393 std::optional<TxVerbosity> tx_verbosity,
394 std::optional<std::pair<size_t, size_t>> block_part = std::nullopt)
395{
396 if (!CheckWarmup(req))
397 return false;
398 std::string hashStr;
399 const RESTResponseFormat rf = ParseDataFormat(hashStr, uri_part);
400
401 auto hash{uint256::FromHex(hashStr)};
402 if (!hash) {
403 return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
404 }
405
406 FlatFilePos pos{};
407 const CBlockIndex* pblockindex = nullptr;
408 const CBlockIndex* tip = nullptr;
409 ChainstateManager* maybe_chainman = GetChainman(context, req);
410 if (!maybe_chainman) return false;
411 ChainstateManager& chainman = *maybe_chainman;
412 {
413 LOCK(cs_main);
414 tip = chainman.ActiveChain().Tip();
415 pblockindex = chainman.m_blockman.LookupBlockIndex(*hash);
416 if (!pblockindex) {
417 return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
418 }
419 if (!(pblockindex->nStatus & BLOCK_HAVE_DATA)) {
420 if (chainman.m_blockman.IsBlockPruned(*pblockindex)) {
421 return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
422 }
423 return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (not fully downloaded)");
424 }
425 pos = pblockindex->GetBlockPos();
426 }
427
428 const auto block_data{chainman.m_blockman.ReadRawBlock(pos, block_part)};
429 if (!block_data) {
430 switch (block_data.error()) {
431 case node::ReadRawError::IO: return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "I/O error reading " + hashStr);
432 case node::ReadRawError::BadPartRange:
433 assert(block_part);
434 return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Bad block part offset/size %d/%d for %s", block_part->first, block_part->second, hashStr));
435 } // no default case, so the compiler can warn about missing cases
436 assert(false);
437 }
438
439 switch (rf) {
440 case RESTResponseFormat::BINARY: {
441 req->WriteHeader("Content-Type", "application/octet-stream");
442 req->WriteReply(HTTP_OK, *block_data);
443 return true;
444 }
445
446 case RESTResponseFormat::HEX: {
447 const std::string strHex{HexStr(*block_data) + "\n"};

Callers 3

rest_block_extendedFunction · 0.85
rest_block_notxdetailsFunction · 0.85
rest_block_partFunction · 0.85

Calls 15

CheckWarmupFunction · 0.85
ParseDataFormatFunction · 0.85
FromHexFunction · 0.85
RESTERRFunction · 0.85
GetChainmanFunction · 0.85
blockToJSONFunction · 0.85
LookupBlockIndexMethod · 0.80
IsBlockPrunedMethod · 0.80
ReadRawBlockMethod · 0.80
WriteHeaderMethod · 0.80
HexStrFunction · 0.50

Tested by

no test coverage detected