Repository: bitcoin/bitcoin
File: src/rest.cpp (C++)

Code before:
    if (!maybe_chainman) return false;
    ChainstateManager& chainman = *maybe_chainman;
    {
        LOCK(cs_main);
        tip = chainman.ActiveChain().Tip();
        pblockindex = chainman.m_blockman.LookupBlockIndex(*hash);
        if (!pblockindex) {
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
        }
        if (!(pblockindex->nStatus & BLOCK_HAVE_DATA)) {
            if (chainman.m_blockman.IsBlockPruned(*pblockindex)) {
                return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
            }
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (not fully downloaded)");
        }
        pos = pblockindex->GetBlockPos();
    }

    std::vector<std::byte> block_data{};
    if (!chainman.m_blockman.ReadRawBlock(block_data, pos)) {
        return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
    }

    switch (rf) {
    case RESTResponseFormat::BINARY: {
        req->WriteHeader("Content-Type", "application/octet-stream");
        req->WriteReply(HTTP_OK, block_data);
        return true;
    }

    case RESTResponseFormat::HEX: {
        const std::string strHex{HexStr(block_data) + "\n"};
        req->WriteHeader("Content-Type", "text/plain");
        req->WriteReply(HTTP_OK, strHex);
        return true;
    }

    case RESTResponseFormat::JSON: {
        CBlock block{};
        DataStream block_stream{block_data};
        block_stream >> TX_WITH_WITNESS(block);
        UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
        std::string strJSON = objBlock.write() + "\n";
        req->WriteHeader("Content-Type", "application/json");
        req->WriteReply(HTTP_OK, strJSON);
        return true;
    }

    default: {
        return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
    }

Review comment (suggestion):
nit
```suggestion
    const auto block_data{chainman.m_blockman.ReadRawBlock(pos, block_part)};
```

Code after:
        return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
    }

    FlatFilePos pos{};
    const CBlockIndex* pblockindex = nullptr;
    const CBlockIndex* tip = nullptr;
    ChainstateManager* maybe_chainman = GetChainman(context, req);
    if (!maybe_chainman) return false;
    ChainstateManager& chainman = *maybe_chainman;
    {
        LOCK(cs_main);
        tip = chainman.ActiveChain().Tip();
        pblockindex = chainman.m_blockman.LookupBlockIndex(*hash);
        if (!pblockindex) {
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
        }
        if (!(pblockindex->nStatus & BLOCK_HAVE_DATA)) {
            if (chainman.m_blockman.IsBlockPruned(*pblockindex)) {
                return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
            }
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (not fully downloaded)");
        }
        pos = pblockindex->GetBlockPos();
    }

    const auto block_data{chainman.m_blockman.ReadRawBlock(pos, block_part)};
    if (!block_data) {
        switch (block_data.error()) {
        case node::ReadRawError::IO: return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "I/O error reading " + hashStr);
        case node::ReadRawError::BadPartRange:
            assert(block_part);
            return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Bad block part offset/size %d/%d for %s", block_part->first, block_part->second, hashStr));
        } // no default case, so the compiler can warn about missing cases
        assert(false);
    }

    switch (rf) {
    case RESTResponseFormat::BINARY: {
        req->WriteHeader("Content-Type", "application/octet-stream");
        req->WriteReply(HTTP_OK, *block_data);
        return true;
    }

    case RESTResponseFormat::HEX: {
        const std::string strHex{HexStr(*block_data) + "\n"};
        req->WriteHeader("Content-Type", "text/plain");
        req->WriteReply(HTTP_OK, strHex);
        return true;
    }

    case RESTResponseFormat::JSON: {