65 uint32_t nTxVerDummy = 0;
66 READWRITE(nTxVerDummy, obj.nHeight, obj.out);
71 std::string message) {
85 auto node_context = util::AnyPtr<NodeContext>(context);
89 "Internal bug detected: Node context not found!\n"
90 "You may report this issue here: %s\n",
91 __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
105 auto node_context = util::AnyPtr<NodeContext>(context);
106 if (!node_context || !node_context->mempool) {
110 return node_context->mempool.get();
122 auto node_context = util::AnyPtr<NodeContext>(context);
123 if (!node_context || !node_context->chainman) {
126 "Internal bug detected: Chainman disabled or instance"
128 "You may report this issue here: %s\n",
129 __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
132 return node_context->chainman.get();
136 const std::string &strReq) {
137 const std::string::size_type pos = strReq.rfind(
'.');
138 if (pos == std::string::npos) {
143 param = strReq.substr(0, pos);
144 const std::string suff(strReq, pos + 1);
146 for (
const auto &rf_name :
rf_names) {
147 if (suff == rf_name.name) {
159 for (
const auto &rf_name :
rf_names) {
160 if (strlen(rf_name.name) > 0) {
162 formats.append(rf_name.name);
163 formats.append(
", ");
167 if (formats.length() > 0) {
168 return formats.substr(0, formats.length() - 2);
175 std::string statusmessage;
178 "Service temporarily unavailable: " + statusmessage);
192 std::vector<std::string> path =
SplitString(param,
'/');
194 if (path.size() != 2) {
196 "No header count specified. Use "
197 "/rest/headers/<count>/<hash>.<ext>.");
200 long count = strtol(path[0].c_str(),
nullptr, 10);
201 if (count < 1 || count > 2000) {
203 "Header count out of range: " + path[0]);
206 std::string hashStr = path[1];
215 std::vector<const CBlockIndex *> headers;
216 headers.reserve(
count);
219 if (!maybe_chainman) {
225 tip = active_chain.
Tip();
227 while (pindex !=
nullptr && active_chain.
Contains(pindex)) {
228 headers.push_back(pindex);
229 if (headers.size() ==
size_t(
count)) {
232 pindex = active_chain.
Next(pindex);
240 ssHeader << pindex->GetBlockHeader();
243 std::string binaryHeader = ssHeader.
str();
244 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
252 ssHeader << pindex->GetBlockHeader();
255 std::string strHex =
HexStr(ssHeader) +
"\n";
265 std::string strJSON = jsonHeaders.
write() +
"\n";
266 req->
WriteHeader(
"Content-Type",
"application/json");
273 "output format not found (available: .bin, .hex, .json)");
280 bool showTxDetails) {
299 if (!maybe_chainman) {
311 if (chainman.
m_blockman.IsBlockPruned(pblockindex)) {
313 hashStr +
" not available (pruned data)");
326 std::string binaryBlock = ssBlock.
str();
327 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
336 std::string strHex =
HexStr(ssBlock) +
"\n";
344 pblockindex, showTxDetails);
345 std::string strJSON = objBlock.
write() +
"\n";
346 req->
WriteHeader(
"Content-Type",
"application/json");
353 "output format not found (available: " +
361 const std::string &strURIPart) {
362 return rest_block(config, context, req, strURIPart,
true);
367 const std::string &strURIPart) {
368 return rest_block(config, context, req, strURIPart,
false);
387 std::string strJSON = chainInfoObject.
write() +
"\n";
388 req->
WriteHeader(
"Content-Type",
"application/json");
394 "output format not found (available: json)");
417 std::string strJSON = mempoolInfoObject.
write() +
"\n";
418 req->
WriteHeader(
"Content-Type",
"application/json");
424 "output format not found (available: json)");
431 const std::string &strURIPart) {
448 std::string strJSON = mempoolObject.
write() +
"\n";
449 req->
WriteHeader(
"Content-Type",
"application/json");
455 "output format not found (available: json)");
461 const std::string &strURIPart) {
474 const TxId txid(hash);
477 g_txindex->BlockUntilSyncedToCurrentChain();
487 Params().GetConsensus(), hashBlock);
498 std::string binaryTx = ssTx.
str();
499 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
509 std::string strHex =
HexStr(ssTx) +
"\n";
518 std::string strJSON = objTx.
write() +
"\n";
519 req->
WriteHeader(
"Content-Type",
"application/json");
526 "output format not found (available: " +
541 std::vector<std::string> uriParts;
542 if (param.length() > 1) {
543 std::string strUriParams = param.substr(1);
548 std::string strRequestMutable = req->
ReadBody();
549 if (strRequestMutable.length() == 0 && uriParts.size() == 0) {
553 bool fInputParsed =
false;
554 bool fCheckMemPool =
false;
555 std::vector<COutPoint> vOutPoints;
561 if (uriParts.size() > 0) {
564 if (uriParts[0] ==
"checkmempool") {
565 fCheckMemPool =
true;
568 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++) {
570 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
571 std::string strOutput =
572 uriParts[i].substr(uriParts[i].find(
'-') + 1);
580 vOutPoints.push_back(
COutPoint(txid, uint32_t(nOutput)));
583 if (vOutPoints.size() > 0) {
593 std::vector<uint8_t> strRequestV =
ParseHex(strRequestMutable);
594 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
600 if (strRequestMutable.size() > 0) {
604 "Combination of URI scheme inputs and "
605 "raw post data is not allowed");
609 oss << strRequestMutable;
610 oss >> fCheckMemPool;
613 }
catch (
const std::ios_base::failure &) {
628 "output format not found (available: " +
637 strprintf(
"Error: max outpoints exceeded (max: %d, tried: %d)",
643 std::vector<uint8_t> bitmap;
644 std::vector<CCoin> outs;
645 std::string bitmapStringRepresentation;
646 std::vector<bool> hits;
647 bitmap.resize((vOutPoints.size() + 7) / 8);
649 if (!maybe_chainman) {
657 [&vOutPoints, &outs, &hits, &active_height, &active_hash,
660 for (
const COutPoint &vOutPoint : vOutPoints) {
662 bool hit = (!mempool || !mempool->isSpent(vOutPoint)) &&
663 view.GetCoin(vOutPoint, coin);
666 outs.emplace_back(std::move(coin));
684 process_utxos(viewMempool, mempool);
688 process_utxos(chainman.ActiveChainstate().CoinsTip(),
nullptr);
691 for (
size_t i = 0; i < hits.size(); ++i) {
692 const bool hit = hits[i];
695 bitmapStringRepresentation.append(hit ?
"1" :
"0");
696 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
705 ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
706 std::string ssGetUTXOResponseString = ssGetUTXOResponse.
str();
708 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
715 ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
716 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
728 objGetUTXOResponse.
pushKV(
"chainHeight", active_height);
729 objGetUTXOResponse.
pushKV(
"chaintipHash", active_hash.
GetHex());
730 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
733 for (
const CCoin &coin : outs) {
735 utxo.
pushKV(
"height", int32_t(coin.nHeight));
736 utxo.
pushKV(
"value", coin.out.nValue);
741 utxo.
pushKV(
"scriptPubKey", o);
744 objGetUTXOResponse.
pushKV(
"utxos", utxos);
747 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
748 req->
WriteHeader(
"Content-Type",
"application/json");
754 "output format not found (available: " +
762 const std::string &str_uri_part) {
766 std::string height_str;
770 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
778 if (!maybe_chainman) {
784 if (blockheight > active_chain.
Height()) {
787 pblockindex = active_chain[blockheight];
793 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
804 req->
WriteHeader(
"Content-Type",
"application/json");
812 "output format not found (available: " +
818 static const struct {
821 const std::string &strReq);
837 const std::string &
prefix) {
838 return up.handler(config, context, req,
prefix);
RPCHelpMan getblockchaininfo()
UniValue blockToJSON(BlockManager &blockman, const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
Block description 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,...
BlockHash GetBlockHash() const
An in-memory indexed chain of blocks.
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.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
const Consensus::Params & GetConsensus() const
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...
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
virtual const CChainParams & GetChainParams() const =0
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 Config &config, 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
CBlockIndex * LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void TxToUniv(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0, const CTxUndo *txundo=nullptr)
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
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.
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const TxId &txid, const Consensus::Params &consensusParams, BlockHash &hashBlock)
Return transaction with a given txid.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params ¶ms)
Functions for disk access for blocks.
Implement std::hash so RCUPtr can be used as a key for maps or sets.
std::shared_ptr< const CTransaction > CTransactionRef
static ChainstateManager * GetChainman(const std::any &context, HTTPRequest *req)
Get the node context chainstatemanager.
static RetFormat ParseDataFormat(std::string ¶m, const std::string &strReq)
static bool rest_blockhash_by_height(Config &config, const std::any &context, HTTPRequest *req, const std::string &str_uri_part)
void StartREST(const std::any &context)
Start HTTP REST subsystem.
bool(* handler)(Config &config, const std::any &context, HTTPRequest *req, const std::string &strReq)
void StopREST()
Stop HTTP REST subsystem.
static bool rest_mempool_info(Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static const struct @12 rf_names[]
static bool rest_headers(Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_block_extended(Config &config, 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_mempool_contents(Config &config, 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 bool CheckWarmup(HTTPRequest *req)
static bool rest_block_notxdetails(Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_block(const Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart, bool showTxDetails)
static bool rest_chaininfo(Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_tx(Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static NodeContext * GetNodeContext(const std::any &context, HTTPRequest *req)
Get the node context.
static const struct @13 uri_prefixes[]
static bool rest_getutxos(Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart)
static const size_t MAX_GETUTXOS_OUTPOINTS
static std::string AvailableDataFormatsString()
HTTPStatusCode
HTTP status codes.
@ HTTP_SERVICE_UNAVAILABLE
@ HTTP_INTERNAL_SERVER_ERROR
bool RPCIsInWarmup(std::string *outStatus)
Returns the current warmup state.
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
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)
Returns true if each character in str is a hex character, and has an even number of hex digits.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::vector< uint8_t > ParseHex(const char *psz)
std::vector< std::string > SplitString(std::string_view str, char sep)
A BlockHash is a unqiue identifier for a block.
SERIALIZE_METHODS(CCoin, obj)
A TxId is the identifier of a transaction.
NodeContext struct containing references to chain state and connection state.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
static const int PROTOCOL_VERSION
network protocol versioning