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 long count = strtol(path[0].c_str(),
nullptr, 10);
193 if (count < 1 || count > 2000)
196 std::string hashStr = path[1];
202 std::vector<const CBlockIndex *> headers;
203 headers.reserve(
count);
206 if (!maybe_chainman)
return false;
210 tip = active_chain.
Tip();
211 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
212 while (pindex !=
nullptr && active_chain.
Contains(pindex)) {
213 headers.push_back(pindex);
214 if (headers.size() == (
unsigned long)
count)
216 pindex = active_chain.
Next(pindex);
224 ssHeader << pindex->GetBlockHeader();
227 std::string binaryHeader = ssHeader.
str();
228 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
236 ssHeader << pindex->GetBlockHeader();
239 std::string strHex =
HexStr(ssHeader) +
"\n";
249 std::string strJSON = jsonHeaders.
write() +
"\n";
250 req->
WriteHeader(
"Content-Type",
"application/json");
262 const std::string& strURIPart,
279 if (!maybe_chainman)
return false;
283 pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
299 std::string binaryBlock = ssBlock.
str();
300 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
308 std::string strHex =
HexStr(ssBlock) +
"\n";
316 std::string strJSON = objBlock.
write() +
"\n";
317 req->
WriteHeader(
"Content-Type",
"application/json");
330 return rest_block(context, req, strURIPart,
true);
335 return rest_block(context, req, strURIPart,
false);
354 std::string strJSON = chainInfoObject.
write() +
"\n";
355 req->
WriteHeader(
"Content-Type",
"application/json");
370 if (!mempool)
return false;
378 std::string strJSON = mempoolInfoObject.
write() +
"\n";
379 req->
WriteHeader(
"Content-Type",
"application/json");
393 if (!mempool)
return false;
401 std::string strJSON = mempoolObject.
write() +
"\n";
402 req->
WriteHeader(
"Content-Type",
"application/json");
424 g_txindex->BlockUntilSyncedToCurrentChain();
428 if (!
node)
return false;
440 std::string binaryTx = ssTx.
str();
441 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
450 std::string strHex =
HexStr(ssTx) +
"\n";
459 std::string strJSON = objTx.
write() +
"\n";
460 req->
WriteHeader(
"Content-Type",
"application/json");
478 std::vector<std::string> uriParts;
479 if (param.length() > 1)
481 std::string strUriParams = param.substr(1);
482 boost::split(uriParts, strUriParams, boost::is_any_of(
"/"));
486 std::string strRequestMutable = req->
ReadBody();
487 if (strRequestMutable.length() == 0 && uriParts.size() == 0)
490 bool fInputParsed =
false;
491 bool fCheckMemPool =
false;
492 std::vector<COutPoint> vOutPoints;
497 if (uriParts.size() > 0)
500 if (uriParts[0] ==
"checkmempool") fCheckMemPool =
true;
502 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
506 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
507 std::string strOutput = uriParts[i].substr(uriParts[i].find(
'-')+1);
513 vOutPoints.push_back(
COutPoint(txid, (uint32_t)nOutput));
516 if (vOutPoints.size() > 0)
525 std::vector<unsigned char> strRequestV =
ParseHex(strRequestMutable);
526 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
533 if (strRequestMutable.size() > 0)
539 oss << strRequestMutable;
540 oss >> fCheckMemPool;
543 }
catch (
const std::ios_base::failure&) {
565 std::vector<unsigned char> bitmap;
566 std::vector<CCoin> outs;
567 std::string bitmapStringRepresentation;
568 std::vector<bool> hits;
569 bitmap.resize((vOutPoints.size() + 7) / 8);
571 if (!maybe_chainman)
return false;
574 auto process_utxos = [&vOutPoints, &outs, &hits](
const CCoinsView& view,
const CTxMemPool& mempool) {
575 for (
const COutPoint& vOutPoint : vOutPoints) {
577 bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin);
579 if (hit) outs.emplace_back(std::move(coin));
585 if (!mempool)
return false;
590 process_utxos(viewMempool, *mempool);
596 for (
size_t i = 0; i < hits.size(); ++i) {
597 const bool hit = hits[i];
598 bitmapStringRepresentation.append(hit ?
"1" :
"0");
599 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
609 std::string ssGetUTXOResponseString = ssGetUTXOResponse.
str();
611 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
619 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
633 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
636 for (
const CCoin& coin : outs) {
638 utxo.
pushKV(
"height", (int32_t)coin.nHeight);
644 utxo.
pushKV(
"scriptPubKey", o);
647 objGetUTXOResponse.
pushKV(
"utxos", utxos);
650 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
651 req->
WriteHeader(
"Content-Type",
"application/json");
662 const std::string& str_uri_part)
665 std::string height_str;
668 int32_t blockheight = -1;
669 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
676 if (!maybe_chainman)
return false;
680 if (blockheight > active_chain.
Height()) {
683 pblockindex = active_chain[blockheight];
689 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
699 req->
WriteHeader(
"Content-Type",
"application/json");
711 static const struct {
std::shared_ptr< const CTransaction > CTransactionRef
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
static ChainstateManager * GetChainman(const std::any &context, HTTPRequest *req)
Get the node context chainstatemanager.
static bool CheckWarmup(HTTPRequest *req)
static RetFormat ParseDataFormat(std::string ¶m, const std::string &strReq)
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
static bool rest_getutxos(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
An in-memory indexed chain of blocks.
static std::string AvailableDataFormatsString()
static bool rest_tx(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
std::vector< unsigned char > ParseHex(const char *psz)
int Height() const
Return the maximal height in the chain.
HTTPStatusCode
HTTP status codes.
UniValue blockheaderToJSON(const CBlockIndex *tip, const CBlockIndex *blockindex)
Block header to JSON.
static const struct @10 uri_prefixes[]
Double ended buffer combining vector and stream-like interfaces.
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
static bool rest_headers(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_block(const std::any &context, HTTPRequest *req, const std::string &strURIPart, bool showTxDetails)
bool(* handler)(const std::any &context, HTTPRequest *req, const std::string &strReq)
void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
Register handler for prefix.
SERIALIZE_METHODS(CCoin, obj)
uint256 GetBlockHash() const
static bool rest_block_extended(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
bool push_back(const UniValue &val)
static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status, std::string message)
NodeContext struct containing references to chain state and connection state.
static bool rest_mempool_contents(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
Abstract view on the open txout dataset.
void WriteReply(int nStatus, const std::string &strReply="")
Write HTTP reply.
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
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...
bool IsHex(const std::string &str)
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
static bool rest_mempool_info(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
Unregister handler for prefix.
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, bool include_addresses, UniValue &entry, bool include_hex=true, int serialize_flags=0, const CTxUndo *txundo=nullptr)
bool pushKV(const std::string &key, const UniValue &val)
An output of a transaction.
An outpoint - a combination of a transaction hash and an index n into its vout.
static const struct @9 rf_names[]
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
Block description to JSON.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
static bool rest_blockhash_by_height(const std::any &context, HTTPRequest *req, const std::string &str_uri_part)
static bool rest_block_notxdetails(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 const size_t MAX_GETUTXOS_OUTPOINTS
RPCHelpMan getblockchaininfo()
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
void StopREST()
Stop HTTP REST subsystem.
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
int RPCSerializationFlags()
static const int PROTOCOL_VERSION
network protocol versioning
static NodeContext * GetNodeContext(const std::any &context, HTTPRequest *req)
Get the node context.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
std::string GetHex() const
UniValue ValueFromAmount(const CAmount amount)
bool RPCIsInWarmup(std::string *outStatus)
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::string ReadBody()
Read request body.
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
CChainState & ActiveChainstate() const
The most-work chain.
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
const Consensus::Params & GetConsensus() const
void InterruptREST()
Interrupt RPC REST subsystem.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
UniValue HandleRequest(const JSONRPCRequest &request) const
void SetHex(const char *psz)
CCoinsView that brings transactions from a mempool into view.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
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.
#define PACKAGE_BUGREPORT
CChain & ActiveChain() const
static bool rest_chaininfo(const std::any &context, HTTPRequest *req, const std::string &strURIPart)
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex, bool include_addresses)
void StartREST(const std::any &context)
Start HTTP REST subsystem.