| 275 | } |
| 276 | |
| 277 | static bool rest_block(const std::any& context, |
| 278 | HTTPRequest* req, |
| 279 | const std::string& strURIPart, |
| 280 | TxVerbosity tx_verbosity) |
| 281 | { |
| 282 | if (!CheckWarmup(req)) |
| 283 | return false; |
| 284 | std::string hashStr; |
| 285 | const RetFormat rf = ParseDataFormat(hashStr, strURIPart); |
| 286 | |
| 287 | uint256 hash; |
| 288 | if (!ParseHashStr(hashStr, hash)) |
| 289 | return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); |
| 290 | |
| 291 | CBlock block; |
| 292 | CBlockIndex* pblockindex = nullptr; |
| 293 | CBlockIndex* tip = nullptr; |
| 294 | { |
| 295 | ChainstateManager* maybe_chainman = GetChainman(context, req); |
| 296 | if (!maybe_chainman) return false; |
| 297 | ChainstateManager& chainman = *maybe_chainman; |
| 298 | LOCK(cs_main); |
| 299 | tip = chainman.ActiveChain().Tip(); |
| 300 | pblockindex = chainman.m_blockman.LookupBlockIndex(hash); |
| 301 | if (!pblockindex) { |
| 302 | return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); |
| 303 | } |
| 304 | |
| 305 | if (IsBlockPruned(pblockindex)) |
| 306 | return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); |
| 307 | |
| 308 | if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) |
| 309 | return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); |
| 310 | } |
| 311 | |
| 312 | switch (rf) { |
| 313 | case RetFormat::BINARY: { |
| 314 | CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); |
| 315 | ssBlock << block; |
| 316 | std::string binaryBlock = ssBlock.str(); |
| 317 | req->WriteHeader("Content-Type", "application/octet-stream"); |
| 318 | req->WriteReply(HTTP_OK, binaryBlock); |
| 319 | return true; |
| 320 | } |
| 321 | |
| 322 | case RetFormat::HEX: { |
| 323 | CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); |
| 324 | ssBlock << block; |
| 325 | std::string strHex = HexStr(ssBlock) + "\n"; |
| 326 | req->WriteHeader("Content-Type", "text/plain"); |
| 327 | req->WriteReply(HTTP_OK, strHex); |
| 328 | return true; |
| 329 | } |
| 330 | |
| 331 | case RetFormat::JSON: { |
| 332 | UniValue objBlock = blockToJSON(block, tip, pblockindex, tx_verbosity); |
| 333 | std::string strJSON = objBlock.write() + "\n"; |
| 334 | req->WriteHeader("Content-Type", "application/json"); |
no test coverage detected