Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
751}753// A bit of a hack - dependency on a function defined in rpc/blockchain.cpp754RPCMethod getblockchaininfo();756static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std::string& uri_part)757{758if (!CheckWarmup(req))759return false;760std::string param;761const RESTResponseFormat rf = ParseDataFormat(param, uri_part);763switch (rf) {764case RESTResponseFormat::JSON: {765JSONRPCRequest jsonRequest;766jsonRequest.context = context;767jsonRequest.params = UniValue(UniValue::VARR);768UniValue chainInfoObject = getblockchaininfo().HandleRequest(jsonRequest);769std::string strJSON = chainInfoObject.write() + "\n";770req->WriteHeader("Cache-Control", REST_CACHE_NO_STORE);771req->WriteHeader("Content-Type", "application/json");772req->WriteReply(HTTP_OK, strJSON);773return true;774}775default: {776return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");777}778}779}782RPCMethod getdeploymentinfo();784static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const std::string& str_uri_part)785{786if (!CheckWarmup(req)) return false;788std::string hash_str;789const RESTResponseFormat rf = ParseDataFormat(hash_str, str_uri_part);790const bool current_tip{hash_str.empty()};792switch (rf) {793case RESTResponseFormat::JSON: {794JSONRPCRequest jsonRequest;795jsonRequest.context = context;796jsonRequest.params = UniValue(UniValue::VARR);798if (!current_tip) {799auto hash{uint256::FromHex(hash_str)};800if (!hash) {801return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hash_str);802}804const ChainstateManager* chainman = GetChainman(context, req);805if (!chainman) return false;806if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(*hash))) {807return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");808}810jsonRequest.params.push_back(hash_str);811}813req->WriteHeader("Cache-Control", current_tip ? REST_CACHE_NO_STORE : REST_CACHE_IMMUTABLE);814req->WriteHeader("Content-Type", "application/json");815req->WriteReply(HTTP_OK, getdeploymentinfo().HandleRequest(jsonRequest).write() + "\n");816return true;817}818default: {819return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");820}821}823}825static bool rest_mempool(const std::any& context, HTTPRequest* req, const std::string& str_uri_part)826{827if (!CheckWarmup(req))828return false;830std::string param;831const RESTResponseFormat rf = ParseDataFormat(param, str_uri_part);832if (param != "contents" && param != "info") {833return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/mempool/<info|contents>.json");834}836const CTxMemPool* mempool = GetMemPool(context, req);837if (!mempool) return false;839switch (rf) {840case RESTResponseFormat::JSON: {841std::string str_json;842if (param == "contents") {843std::string raw_verbose;844try {845raw_verbose = req->GetQueryParameter("verbose").value_or("true");846} catch (const std::runtime_error& e) {847return RESTERR(req, HTTP_BAD_REQUEST, e.what());848}849if (raw_verbose != "true" && raw_verbose != "false") {850return RESTERR(req, HTTP_BAD_REQUEST, "The \"verbose\" query parameter must be either \"true\" or \"false\".");851}852std::string raw_mempool_sequence;853try {854raw_mempool_sequence = req->GetQueryParameter("mempool_sequence").value_or("false");855} catch (const std::runtime_error& e) {856return RESTERR(req, HTTP_BAD_REQUEST, e.what());857}858if (raw_mempool_sequence != "true" && raw_mempool_sequence != "false") {859return RESTERR(req, HTTP_BAD_REQUEST, "The \"mempool_sequence\" query parameter must be either \"true\" or \"false\".");860}861const bool verbose{raw_verbose == "true"};862const bool mempool_sequence{raw_mempool_sequence == "true"};863if (verbose && mempool_sequence) {864return RESTERR(req, HTTP_BAD_REQUEST, "Verbose results cannot contain mempool sequence values. (hint: set \"verbose=false\")");865}866str_json = MempoolToJSON(*mempool, verbose, mempool_sequence).write() + "\n";867} else {868str_json = MempoolInfoToJSON(*mempool).write() + "\n";869}871req->WriteHeader("Cache-Control", REST_CACHE_NO_STORE);872req->WriteHeader("Content-Type", "application/json");873req->WriteReply(HTTP_OK, str_json);874return true;875}876default: {877return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");878}879}880}882static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string& uri_part)883{884if (!CheckWarmup(req))885return false;886std::string hashStr;887const RESTResponseFormat rf = ParseDataFormat(hashStr, uri_part);889auto hash{Txid::FromHex(hashStr)};890if (!hash) {891return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);892}894if (g_txindex) {895g_txindex->BlockUntilSyncedToCurrentChain();896}898const NodeContext* const node = GetNodeContext(context, req);899if (!node) return false;900uint256 hashBlock = uint256();901const CTransactionRef tx{GetTransaction(/*block_index=*/nullptr, node->mempool.get(), *hash, node->chainman->m_blockman, hashBlock)};902if (!tx) {903return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");904}905switch (rf) {906case RESTResponseFormat::BINARY: {907DataStream ssTx;908ssTx << TX_WITH_WITNESS(tx);910req->WriteHeader("Cache-Control", REST_CACHE_NO_STORE);911req->WriteHeader("Content-Type", "application/octet-stream");912req->WriteReply(HTTP_OK, ssTx);913return true;914}916case RESTResponseFormat::HEX: {917DataStream ssTx;918ssTx << TX_WITH_WITNESS(tx);920std::string strHex = HexStr(ssTx) + "\n";921req->WriteHeader("Cache-Control", REST_CACHE_NO_STORE);922req->WriteHeader("Content-Type", "text/plain");923req->WriteReply(HTTP_OK, strHex);924return true;925}927case RESTResponseFormat::JSON: {928UniValue objTx(UniValue::VOBJ);929TxToUniv(*tx, /*block_hash=*/hashBlock, /*entry=*/ objTx);930std::string strJSON = objTx.write() + "\n";931req->WriteHeader("Cache-Control", REST_CACHE_NO_STORE);932req->WriteHeader("Content-Type", "application/json");933req->WriteReply(HTTP_OK, strJSON);934return true;935}937default: {938return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");939}940}941}943static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::string& uri_part)944{945if (!CheckWarmup(req))946return false;947std::string param;948const RESTResponseFormat rf = ParseDataFormat(param, uri_part);950std::vector<std::string> uriParts;951if (param.length() > 1)952{953std::string strUriParams = param.substr(1);954uriParts = SplitString(strUriParams, '/');955}957// throw exception in case of an empty request958std::string strRequestMutable = req->ReadBody();959if (strRequestMutable.length() == 0 && uriParts.size() == 0)960return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");962bool fInputParsed = false;963bool fCheckMemPool = false;964std::vector<COutPoint> vOutPoints;966// parse/deserialize input967// input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ...969if (uriParts.size() > 0)970{971//inputs is sent over URI scheme (/rest/getutxos/checkmempool/txid1-n/txid2-n/...)972if (uriParts[0] == "checkmempool") fCheckMemPool = true;974for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)975{976const auto txid_out{util::Split<std::string_view>(uriParts[i], '-')};977if (txid_out.size() != 2) {978return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");979}980auto txid{Txid::FromHex(txid_out.at(0))};981auto output{ToIntegral<uint32_t>(txid_out.at(1))};983if (!txid || !output) {984return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");985}987vOutPoints.emplace_back(*txid, *output);988}990if (vOutPoints.size() > 0)991fInputParsed = true;992else993return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");994}996switch (rf) {997case RESTResponseFormat::HEX: {998// convert hex to bin, continue then with bin part999std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable);1000strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.