diff options
Diffstat (limited to 'src/rest.cpp')
-rw-r--r-- | src/rest.cpp | 102 |
1 files changed, 52 insertions, 50 deletions
diff --git a/src/rest.cpp b/src/rest.cpp index eeeb3f5141..5871b554a6 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -24,21 +24,21 @@ static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once -enum RetFormat { - RF_UNDEF, - RF_BINARY, - RF_HEX, - RF_JSON, +enum class RetFormat { + UNDEF, + BINARY, + HEX, + JSON, }; static const struct { enum RetFormat rf; const char* name; } rf_names[] = { - {RF_UNDEF, ""}, - {RF_BINARY, "bin"}, - {RF_HEX, "hex"}, - {RF_JSON, "json"}, + {RetFormat::UNDEF, ""}, + {RetFormat::BINARY, "bin"}, + {RetFormat::HEX, "hex"}, + {RetFormat::JSON, "json"}, }; struct CCoin { @@ -90,7 +90,7 @@ static enum RetFormat ParseDataFormat(std::string& param, const std::string& str static std::string AvailableDataFormatsString() { - std::string formats = ""; + std::string formats; for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) if (strlen(rf_names[i].name) > 0) { formats.append("."); @@ -147,8 +147,7 @@ static bool rest_headers(HTTPRequest* req, headers.reserve(count); { LOCK(cs_main); - BlockMap::const_iterator it = mapBlockIndex.find(hash); - const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : nullptr; + const CBlockIndex* pindex = LookupBlockIndex(hash); while (pindex != nullptr && chainActive.Contains(pindex)) { headers.push_back(pindex); if (headers.size() == (unsigned long)count) @@ -163,20 +162,20 @@ static bool rest_headers(HTTPRequest* req, } switch (rf) { - case RF_BINARY: { + case RetFormat::BINARY: { std::string binaryHeader = ssHeader.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryHeader); return true; } - case RF_HEX: { + case RetFormat::HEX: { std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; } - case RF_JSON: { + case RetFormat::JSON: { UniValue jsonHeaders(UniValue::VARR); { LOCK(cs_main); @@ -212,10 +211,11 @@ static bool rest_block(HTTPRequest* req, CBlockIndex* pblockindex = nullptr; { LOCK(cs_main); - if (mapBlockIndex.count(hash) == 0) + pblockindex = LookupBlockIndex(hash); + if (!pblockindex) { return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); + } - pblockindex = mapBlockIndex[hash]; if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); @@ -227,21 +227,21 @@ static bool rest_block(HTTPRequest* req, ssBlock << block; switch (rf) { - case RF_BINARY: { + case RetFormat::BINARY: { std::string binaryBlock = ssBlock.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryBlock); return true; } - case RF_HEX: { + case RetFormat::HEX: { std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; } - case RF_JSON: { + case RetFormat::JSON: { UniValue objBlock; { LOCK(cs_main); @@ -280,7 +280,7 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { - case RF_JSON: { + case RetFormat::JSON: { JSONRPCRequest jsonRequest; jsonRequest.params = UniValue(UniValue::VARR); UniValue chainInfoObject = getblockchaininfo(jsonRequest); @@ -303,7 +303,7 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { - case RF_JSON: { + case RetFormat::JSON: { UniValue mempoolInfoObject = mempoolInfoToJSON(); std::string strJSON = mempoolInfoObject.write() + "\n"; @@ -325,7 +325,7 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { - case RF_JSON: { + case RetFormat::JSON: { UniValue mempoolObject = mempoolToJSON(true); std::string strJSON = mempoolObject.write() + "\n"; @@ -359,21 +359,21 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) ssTx << tx; switch (rf) { - case RF_BINARY: { + case RetFormat::BINARY: { std::string binaryTx = ssTx.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryTx); return true; } - case RF_HEX: { + case RetFormat::HEX: { std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; } - case RF_JSON: { + case RetFormat::JSON: { UniValue objTx(UniValue::VOBJ); TxToUniv(*tx, hashBlock, objTx); std::string strJSON = objTx.write() + "\n"; @@ -440,13 +440,13 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) } switch (rf) { - case RF_HEX: { + case RetFormat::HEX: { // convert hex to bin, continue then with bin part std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable); strRequestMutable.assign(strRequestV.begin(), strRequestV.end()); } - case RF_BINARY: { + case RetFormat::BINARY: { try { //deserialize only if user sent a request if (strRequestMutable.size() > 0) @@ -466,7 +466,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) break; } - case RF_JSON: { + case RetFormat::JSON: { if (!fInputParsed) return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); break; @@ -487,33 +487,35 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) std::vector<bool> hits; bitmap.resize((vOutPoints.size() + 7) / 8); { - LOCK2(cs_main, mempool.cs); - - CCoinsView viewDummy; - CCoinsViewCache view(&viewDummy); - - CCoinsViewCache& viewChain = *pcoinsTip; - CCoinsViewMemPool viewMempool(&viewChain, mempool); - - if (fCheckMemPool) - view.SetBackend(viewMempool); // switch cache backend to db+mempool in case user likes to query mempool - - for (size_t i = 0; i < vOutPoints.size(); i++) { - bool hit = false; - Coin coin; - if (view.GetCoin(vOutPoints[i], coin) && !mempool.isSpent(vOutPoints[i])) { - hit = true; - outs.emplace_back(std::move(coin)); + auto process_utxos = [&vOutPoints, &outs, &hits](const CCoinsView& view, const CTxMemPool& mempool) { + for (const COutPoint& vOutPoint : vOutPoints) { + Coin coin; + bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin); + hits.push_back(hit); + if (hit) outs.emplace_back(std::move(coin)); } + }; + + if (fCheckMemPool) { + // use db+mempool as cache backend in case user likes to query mempool + LOCK2(cs_main, mempool.cs); + CCoinsViewCache& viewChain = *pcoinsTip; + CCoinsViewMemPool viewMempool(&viewChain, mempool); + process_utxos(viewMempool, mempool); + } else { + LOCK(cs_main); // no need to lock mempool! + process_utxos(*pcoinsTip, CTxMemPool()); + } - hits.push_back(hit); + for (size_t i = 0; i < hits.size(); ++i) { + const bool hit = hits[i]; bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output) bitmap[i / 8] |= ((uint8_t)hit) << (i % 8); } } switch (rf) { - case RF_BINARY: { + case RetFormat::BINARY: { // serialize data // use exact same output as mentioned in Bip64 CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); @@ -525,7 +527,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) return true; } - case RF_HEX: { + case RetFormat::HEX: { CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; @@ -535,7 +537,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) return true; } - case RF_JSON: { + case RetFormat::JSON: { UniValue objGetUTXOResponse(UniValue::VOBJ); // pack in some essentials |