26 #include <boost/algorithm/string.hpp>
58 uint32_t nTxVerDummy = 0;
59 READWRITE(nTxVerDummy, obj.nHeight, obj.out);
83 "Internal bug detected: Node context not found!\n"
84 "You may report this issue here: %s\n",
110 const std::string::size_type pos = strReq.rfind(
'.');
111 if (pos == std::string::npos)
117 param = strReq.substr(0, pos);
118 const std::string suff(strReq, pos + 1);
136 formats.append(
", ");
139 if (formats.length() > 0)
140 return formats.substr(0, formats.length() - 2);
147 std::string statusmessage;
155 const std::string& strURIPart)
161 std::vector<std::string> path;
162 boost::split(path, param, boost::is_any_of(
"/"));
164 if (path.size() != 2)
167 long count = strtol(path[0].c_str(),
nullptr, 10);
168 if (count < 1 || count > 2000)
171 std::string hashStr = path[1];
177 std::vector<const CBlockIndex *> headers;
178 headers.reserve(
count);
183 while (pindex !=
nullptr && ::
ChainActive().Contains(pindex)) {
184 headers.push_back(pindex);
185 if (headers.size() == (
unsigned long)
count)
195 ssHeader << pindex->GetBlockHeader();
198 std::string binaryHeader = ssHeader.
str();
199 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
207 ssHeader << pindex->GetBlockHeader();
210 std::string strHex =
HexStr(ssHeader) +
"\n";
220 std::string strJSON = jsonHeaders.
write() +
"\n";
221 req->
WriteHeader(
"Content-Type",
"application/json");
232 const std::string& strURIPart,
266 std::string binaryBlock = ssBlock.
str();
267 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
275 std::string strHex =
HexStr(ssBlock) +
"\n";
283 std::string strJSON = objBlock.
write() +
"\n";
284 req->
WriteHeader(
"Content-Type",
"application/json");
320 std::string strJSON = chainInfoObject.
write() +
"\n";
321 req->
WriteHeader(
"Content-Type",
"application/json");
336 if (!mempool)
return false;
344 std::string strJSON = mempoolInfoObject.
write() +
"\n";
345 req->
WriteHeader(
"Content-Type",
"application/json");
359 if (!mempool)
return false;
367 std::string strJSON = mempoolObject.
write() +
"\n";
368 req->
WriteHeader(
"Content-Type",
"application/json");
390 g_txindex->BlockUntilSyncedToCurrentChain();
394 if (!node)
return false;
406 std::string binaryTx = ssTx.
str();
407 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
416 std::string strHex =
HexStr(ssTx) +
"\n";
425 std::string strJSON = objTx.
write() +
"\n";
426 req->
WriteHeader(
"Content-Type",
"application/json");
444 std::vector<std::string> uriParts;
445 if (param.length() > 1)
447 std::string strUriParams = param.substr(1);
448 boost::split(uriParts, strUriParams, boost::is_any_of(
"/"));
452 std::string strRequestMutable = req->
ReadBody();
453 if (strRequestMutable.length() == 0 && uriParts.size() == 0)
456 bool fInputParsed =
false;
457 bool fCheckMemPool =
false;
458 std::vector<COutPoint> vOutPoints;
463 if (uriParts.size() > 0)
466 if (uriParts[0] ==
"checkmempool") fCheckMemPool =
true;
468 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
472 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
473 std::string strOutput = uriParts[i].substr(uriParts[i].find(
'-')+1);
479 vOutPoints.push_back(
COutPoint(txid, (uint32_t)nOutput));
482 if (vOutPoints.size() > 0)
491 std::vector<unsigned char> strRequestV =
ParseHex(strRequestMutable);
492 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
498 if (strRequestMutable.size() > 0)
504 oss << strRequestMutable;
505 oss >> fCheckMemPool;
508 }
catch (
const std::ios_base::failure&) {
530 std::vector<unsigned char> bitmap;
531 std::vector<CCoin> outs;
532 std::string bitmapStringRepresentation;
533 std::vector<bool> hits;
534 bitmap.resize((vOutPoints.size() + 7) / 8);
536 auto process_utxos = [&vOutPoints, &outs, &hits](
const CCoinsView& view,
const CTxMemPool& mempool) {
537 for (
const COutPoint& vOutPoint : vOutPoints) {
539 bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin);
541 if (hit) outs.emplace_back(std::move(coin));
547 if (!mempool)
return false;
552 process_utxos(viewMempool, *mempool);
558 for (
size_t i = 0; i < hits.size(); ++i) {
559 const bool hit = hits[i];
560 bitmapStringRepresentation.append(hit ?
"1" :
"0");
561 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
571 std::string ssGetUTXOResponseString = ssGetUTXOResponse.
str();
573 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
581 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
594 objGetUTXOResponse.
pushKV(
"chaintipHash", ::
ChainActive().Tip()->GetBlockHash().GetHex());
595 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
598 for (
const CCoin& coin : outs) {
600 utxo.
pushKV(
"height", (int32_t)coin.nHeight);
606 utxo.
pushKV(
"scriptPubKey", o);
609 objGetUTXOResponse.
pushKV(
"utxos", utxos);
612 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
613 req->
WriteHeader(
"Content-Type",
"application/json");
624 const std::string& str_uri_part)
627 std::string height_str;
630 int32_t blockheight = -1;
631 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
647 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
657 req->
WriteHeader(
"Content-Type",
"application/json");
669 static const struct {
#define PACKAGE_BUGREPORT
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
Block description to JSON.
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
UniValue blockheaderToJSON(const CBlockIndex *tip, const CBlockIndex *blockindex)
Block header to JSON.
const CChainParams & Params()
Return the currently selected parameters.
The block chain is a tree shaped structure starting with the genesis block at the root,...
uint256 GetBlockHash() const
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
int Height() const
Return the maximal height in the chain.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Abstract view on the open txout dataset.
CCoinsView that brings transactions from a mempool into view.
Double ended buffer combining vector and stream-like interfaces.
An outpoint - a combination of a transaction hash and an index n into its vout.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
An output of a transaction.
void WriteReply(int nStatus, const std::string &strReply="")
Write HTTP reply.
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
std::string ReadBody()
Read request body.
UniValue HandleRequest(const JSONRPCRequest &request)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool push_back(const UniValue &val)
bool pushKV(const std::string &key, const UniValue &val)
void SetHex(const char *psz)
std::string GetHex() const
Type-safe dynamic reference.
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
UniValue ValueFromAmount(const CAmount &amount)
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
Unregister handler for prefix.
void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
Register handler for prefix.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
std::shared_ptr< const CTransaction > CTransactionRef
static bool rest_mempool_contents(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
bool(* handler)(const util::Ref &context, HTTPRequest *req, const std::string &strReq)
static const struct @9 uri_prefixes[]
static NodeContext * GetNodeContext(const util::Ref &context, HTTPRequest *req)
Get the node context.
static RetFormat ParseDataFormat(std::string ¶m, const std::string &strReq)
static CTxMemPool * GetMemPool(const util::Ref &context, HTTPRequest *req)
Get the node context mempool.
static bool rest_getutxos(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_blockhash_by_height(const util::Ref &context, HTTPRequest *req, const std::string &str_uri_part)
void StopREST()
Stop HTTP REST subsystem.
static bool rest_tx(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_block(HTTPRequest *req, const std::string &strURIPart, bool showTxDetails)
RPCHelpMan getblockchaininfo()
void StartREST(const util::Ref &context)
Start HTTP REST subsystem.
void InterruptREST()
Interrupt RPC REST subsystem.
static const struct @8 rf_names[]
static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status, std::string message)
static bool rest_block_extended(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_mempool_info(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_chaininfo(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static bool CheckWarmup(HTTPRequest *req)
static bool rest_block_notxdetails(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static const size_t MAX_GETUTXOS_OUTPOINTS
static std::string AvailableDataFormatsString()
static bool rest_headers(const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
HTTPStatusCode
HTTP status codes.
@ HTTP_SERVICE_UNAVAILABLE
@ HTTP_INTERNAL_SERVER_ERROR
bool RPCIsInWarmup(std::string *outStatus)
int RPCSerializationFlags()
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::vector< unsigned char > ParseHex(const char *psz)
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
bool IsHex(const std::string &str)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
SERIALIZE_METHODS(CCoin, obj)
NodeContext struct containing references to chain state and connection state.
std::unique_ptr< CTxMemPool > mempool
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
CBlockIndex * LookupBlockIndex(const uint256 &hash)
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const uint256 &hash, const Consensus::Params &consensusParams, uint256 &hashBlock)
Return transaction from the block at block_index.
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
static const int PROTOCOL_VERSION
network protocol versioning