28#include <boost/algorithm/string.hpp>
60 uint32_t nTxVerDummy = 0;
61 READWRITE(nTxVerDummy, obj.nHeight, obj.out);
81 auto node_context = util::AnyPtr<NodeContext>(context);
85 "Internal bug detected: Node context not found!\n"
86 "You may report this issue here: %s\n",
102 auto node_context = util::AnyPtr<NodeContext>(context);
103 if (!node_context || !node_context->mempool) {
107 return node_context->mempool.get();
119 auto node_context = util::AnyPtr<NodeContext>(context);
120 if (!node_context || !node_context->chainman) {
123 "Internal bug detected: Chainman disabled or instance not found!\n"
124 "You may report this issue here: %s\n",
128 return node_context->chainman.get();
133 const std::string::size_type pos = strReq.rfind(
'.');
134 if (pos == std::string::npos)
140 param = strReq.substr(0, pos);
141 const std::string suff(strReq, pos + 1);
143 for (
const auto& rf_name :
rf_names) {
144 if (suff == rf_name.name)
156 for (
const auto& rf_name :
rf_names) {
157 if (strlen(rf_name.name) > 0) {
159 formats.append(rf_name.name);
160 formats.append(
", ");
164 if (formats.length() > 0)
165 return formats.substr(0, formats.length() - 2);
172 std::string statusmessage;
180 const std::string& strURIPart)
186 std::vector<std::string> path;
187 boost::split(path, param, boost::is_any_of(
"/"));
189 if (path.size() != 2)
192 const auto parsed_count{ToIntegral<size_t>(path[0])};
193 if (!parsed_count.has_value() || *parsed_count < 1 || *parsed_count > 2000) {
197 std::string hashStr = path[1];
203 std::vector<const CBlockIndex*> headers;
204 headers.reserve(*parsed_count);
207 if (!maybe_chainman)
return false;
211 tip = active_chain.
Tip();
212 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
213 while (pindex !=
nullptr && active_chain.
Contains(pindex)) {
214 headers.push_back(pindex);
215 if (headers.size() == *parsed_count) {
218 pindex = active_chain.
Next(pindex);
226 ssHeader << pindex->GetBlockHeader();
229 std::string binaryHeader = ssHeader.
str();
230 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
238 ssHeader << pindex->GetBlockHeader();
241 std::string strHex =
HexStr(ssHeader) +
"\n";
251 std::string strJSON = jsonHeaders.
write() +
"\n";
252 req->
WriteHeader(
"Content-Type",
"application/json");
264 const std::string& strURIPart,
281 if (!maybe_chainman)
return false;
285 pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
301 std::string binaryBlock = ssBlock.
str();
302 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
310 std::string strHex =
HexStr(ssBlock) +
"\n";
318 std::string strJSON = objBlock.
write() +
"\n";
319 req->
WriteHeader(
"Content-Type",
"application/json");
356 std::string strJSON = chainInfoObject.
write() +
"\n";
357 req->
WriteHeader(
"Content-Type",
"application/json");
372 if (!mempool)
return false;
380 std::string strJSON = mempoolInfoObject.
write() +
"\n";
381 req->
WriteHeader(
"Content-Type",
"application/json");
395 if (!mempool)
return false;
403 std::string strJSON = mempoolObject.
write() +
"\n";
404 req->
WriteHeader(
"Content-Type",
"application/json");
426 g_txindex->BlockUntilSyncedToCurrentChain();
430 if (!
node)
return false;
442 std::string binaryTx = ssTx.
str();
443 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
452 std::string strHex =
HexStr(ssTx) +
"\n";
461 std::string strJSON = objTx.
write() +
"\n";
462 req->
WriteHeader(
"Content-Type",
"application/json");
480 std::vector<std::string> uriParts;
481 if (param.length() > 1)
483 std::string strUriParams = param.substr(1);
484 boost::split(uriParts, strUriParams, boost::is_any_of(
"/"));
488 std::string strRequestMutable = req->
ReadBody();
489 if (strRequestMutable.length() == 0 && uriParts.size() == 0)
492 bool fInputParsed =
false;
493 bool fCheckMemPool =
false;
494 std::vector<COutPoint> vOutPoints;
499 if (uriParts.size() > 0)
502 if (uriParts[0] ==
"checkmempool") fCheckMemPool =
true;
504 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
508 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
509 std::string strOutput = uriParts[i].substr(uriParts[i].find(
'-')+1);
515 vOutPoints.push_back(
COutPoint(txid, (uint32_t)nOutput));
518 if (vOutPoints.size() > 0)
527 std::vector<unsigned char> strRequestV =
ParseHex(strRequestMutable);
528 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
535 if (strRequestMutable.size() > 0)
541 oss << strRequestMutable;
542 oss >> fCheckMemPool;
545 }
catch (
const std::ios_base::failure&) {
567 std::vector<unsigned char> bitmap;
568 std::vector<CCoin> outs;
569 std::string bitmapStringRepresentation;
570 std::vector<bool> hits;
571 bitmap.resize((vOutPoints.size() + 7) / 8);
573 if (!maybe_chainman)
return false;
576 auto process_utxos = [&vOutPoints, &outs, &hits](
const CCoinsView& view,
const CTxMemPool& mempool) {
577 for (
const COutPoint& vOutPoint : vOutPoints) {
579 bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin);
581 if (hit) outs.emplace_back(std::move(coin));
587 if (!mempool)
return false;
592 process_utxos(viewMempool, *mempool);
598 for (
size_t i = 0; i < hits.size(); ++i) {
599 const bool hit = hits[i];
600 bitmapStringRepresentation.append(hit ?
"1" :
"0");
601 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
611 std::string ssGetUTXOResponseString = ssGetUTXOResponse.
str();
613 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
621 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
635 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
638 for (
const CCoin& coin : outs) {
640 utxo.
pushKV(
"height", (int32_t)coin.nHeight);
646 utxo.
pushKV(
"scriptPubKey", o);
649 objGetUTXOResponse.
pushKV(
"utxos", utxos);
652 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
653 req->
WriteHeader(
"Content-Type",
"application/json");
664 const std::string& str_uri_part)
667 std::string height_str;
670 int32_t blockheight = -1;
671 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
678 if (!maybe_chainman)
return false;
682 if (blockheight > active_chain.
Height()) {
685 pblockindex = active_chain[blockheight];
691 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
701 req->
WriteHeader(
"Content-Type",
"application/json");
#define PACKAGE_BUGREPORT
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, TxVerbosity verbosity)
Block description 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.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
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
An in-memory indexed chain of blocks.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
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...
int Height() const
Return the maximal height in the chain.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this 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.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
CChainState & ActiveChainstate() const
The most-work chain.
CChain & ActiveChain() const
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) const
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
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
TxVerbosity
Verbose level for block's transaction.
@ SHOW_DETAILS_AND_PREVOUT
The same as previous option with information about prevouts if available.
@ SHOW_TXID
Only TXID for each block's transaction.
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool include_hex, bool include_address=true)
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0, const CTxUndo *txundo=nullptr, TxVerbosity verbosity=TxVerbosity::SHOW_DETAILS)
UniValue ValueFromAmount(const CAmount amount)
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.
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const uint256 &hash, const Consensus::Params &consensusParams, uint256 &hashBlock)
Return transaction with a given hash.
std::shared_ptr< const CTransaction > CTransactionRef
static bool rest_blockhash_by_height(const std::any &context, HTTPRequest *req, const std::string &str_uri_part)
static bool rest_getutxos(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_headers(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static RetFormat ParseDataFormat(std::string ¶m, const std::string &strReq)
static bool rest_tx(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
void StartREST(const std::any &context)
Start HTTP REST subsystem.
static bool rest_mempool_contents(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_block_notxdetails(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
bool(* handler)(const std::any &context, HTTPRequest *req, const std::string &strReq)
static const struct @10 uri_prefixes[]
void StopREST()
Stop HTTP REST subsystem.
RPCHelpMan getblockchaininfo()
static bool rest_chaininfo(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_mempool_info(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
void InterruptREST()
Interrupt RPC REST subsystem.
static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status, std::string message)
static const struct @9 rf_names[]
static bool CheckWarmup(HTTPRequest *req)
static ChainstateManager * GetChainman(const std::any &context, HTTPRequest *req)
Get the node context chainstatemanager.
static bool rest_block_extended(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static CTxMemPool * GetMemPool(const std::any &context, HTTPRequest *req)
Get the node context mempool.
static bool rest_block(const std::any &context, HTTPRequest *req, const std::string &strURIPart, TxVerbosity tx_verbosity)
static const size_t MAX_GETUTXOS_OUTPOINTS
static std::string AvailableDataFormatsString()
static NodeContext * GetNodeContext(const std::any &context, HTTPRequest *req)
Get the node context.
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.
SERIALIZE_METHODS(CCoin, obj)
NodeContext struct containing references to chain state and connection state.
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
static const int PROTOCOL_VERSION
network protocol versioning