63 uint32_t nTxVerDummy = 0;
64 READWRITE(nTxVerDummy, obj.nHeight, obj.out);
69 std::string message) {
83 auto node_context = util::AnyPtr<NodeContext>(context);
87 "Internal bug detected: Node context not found!\n"
88 "You may report this issue here: %s\n",
89 __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
103 auto node_context = util::AnyPtr<NodeContext>(context);
104 if (!node_context || !node_context->mempool) {
108 return node_context->mempool.get();
120 auto node_context = util::AnyPtr<NodeContext>(context);
121 if (!node_context || !node_context->chainman) {
124 "Internal bug detected: Chainman disabled or instance"
126 "You may report this issue here: %s\n",
127 __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
130 return node_context->chainman.get();
134 const std::string &strReq) {
135 const std::string::size_type pos = strReq.rfind(
'.');
136 if (pos == std::string::npos) {
141 param = strReq.substr(0, pos);
142 const std::string suff(strReq, pos + 1);
144 for (
const auto &rf_name :
rf_names) {
145 if (suff == rf_name.name) {
157 for (
const auto &rf_name :
rf_names) {
158 if (strlen(rf_name.name) > 0) {
160 formats.append(rf_name.name);
161 formats.append(
", ");
165 if (formats.length() > 0) {
166 return formats.substr(0, formats.length() - 2);
173 std::string statusmessage;
176 "Service temporarily unavailable: " + statusmessage);
190 std::vector<std::string> path =
SplitString(param,
'/');
192 if (path.size() != 2) {
194 "No header count specified. Use "
195 "/rest/headers/<count>/<hash>.<ext>.");
198 long count = strtol(path[0].c_str(),
nullptr, 10);
199 if (count < 1 || count > 2000) {
201 "Header count out of range: " + path[0]);
204 const std::string &hashStr = path[1];
213 std::vector<const CBlockIndex *> headers;
214 headers.reserve(
count);
217 if (!maybe_chainman) {
223 tip = active_chain.
Tip();
225 while (pindex !=
nullptr && active_chain.
Contains(pindex)) {
226 headers.push_back(pindex);
227 if (headers.size() ==
size_t(
count)) {
230 pindex = active_chain.
Next(pindex);
238 ssHeader << pindex->GetBlockHeader();
241 std::string binaryHeader = ssHeader.
str();
242 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
250 ssHeader << pindex->GetBlockHeader();
253 std::string strHex =
HexStr(ssHeader) +
"\n";
263 std::string strJSON = jsonHeaders.
write() +
"\n";
264 req->
WriteHeader(
"Content-Type",
"application/json");
271 "output format not found (available: .bin, .hex, .json)");
297 if (!maybe_chainman) {
308 if (chainman.
m_blockman.IsBlockPruned(*pblockindex)) {
310 hashStr +
" not available (pruned data)");
321 std::string binaryBlock = ssBlock.str();
322 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
330 std::string strHex =
HexStr(ssBlock) +
"\n";
338 *pblockindex, tx_verbosity);
339 std::string strJSON = objBlock.
write() +
"\n";
340 req->
WriteHeader(
"Content-Type",
"application/json");
347 "output format not found (available: " +
355 const std::string &strURIPart) {
356 return rest_block(config, context, req, strURIPart,
362 const std::string &strURIPart) {
382 std::string strJSON = chainInfoObject.
write() +
"\n";
383 req->
WriteHeader(
"Content-Type",
"application/json");
389 "output format not found (available: json)");
412 std::string strJSON = mempoolInfoObject.
write() +
"\n";
413 req->
WriteHeader(
"Content-Type",
"application/json");
419 "output format not found (available: json)");
426 const std::string &strURIPart) {
443 std::string strJSON = mempoolObject.
write() +
"\n";
444 req->
WriteHeader(
"Content-Type",
"application/json");
450 "output format not found (available: json)");
456 const std::string &strURIPart) {
469 const TxId txid(hash);
472 g_txindex->BlockUntilSyncedToCurrentChain();
482 hashBlock,
node->chainman->m_blockman);
492 std::string binaryTx = ssTx.
str();
493 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
502 std::string strHex =
HexStr(ssTx) +
"\n";
511 std::string strJSON = objTx.
write() +
"\n";
512 req->
WriteHeader(
"Content-Type",
"application/json");
519 "output format not found (available: " +
534 std::vector<std::string> uriParts;
535 if (param.length() > 1) {
536 std::string strUriParams = param.substr(1);
541 std::string strRequestMutable = req->
ReadBody();
542 if (strRequestMutable.length() == 0 && uriParts.size() == 0) {
546 bool fInputParsed =
false;
547 bool fCheckMemPool =
false;
548 std::vector<COutPoint> vOutPoints;
554 if (uriParts.size() > 0) {
557 if (uriParts[0] ==
"checkmempool") {
558 fCheckMemPool =
true;
561 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++) {
563 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
564 std::string strOutput =
565 uriParts[i].substr(uriParts[i].find(
'-') + 1);
573 vOutPoints.push_back(COutPoint(txid, uint32_t(nOutput)));
576 if (vOutPoints.size() > 0) {
586 std::vector<uint8_t> strRequestV =
ParseHex(strRequestMutable);
587 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
593 if (strRequestMutable.size() > 0) {
597 "Combination of URI scheme inputs and "
598 "raw post data is not allowed");
602 oss << strRequestMutable;
603 oss >> fCheckMemPool;
606 }
catch (
const std::ios_base::failure &) {
621 "output format not found (available: " +
630 strprintf(
"Error: max outpoints exceeded (max: %d, tried: %d)",
636 std::vector<uint8_t> bitmap;
637 std::vector<CCoin> outs;
638 std::string bitmapStringRepresentation;
639 std::vector<bool> hits;
640 bitmap.resize((vOutPoints.size() + 7) / 8);
642 if (!maybe_chainman) {
650 [&vOutPoints, &outs, &hits, &active_height, &active_hash,
653 for (
const COutPoint &vOutPoint : vOutPoints) {
655 bool hit = (!mempool || !mempool->isSpent(vOutPoint)) &&
656 view.GetCoin(vOutPoint, coin);
659 outs.emplace_back(std::move(coin));
677 process_utxos(viewMempool, mempool);
684 for (
size_t i = 0; i < hits.size(); ++i) {
685 const bool hit = hits[i];
688 bitmapStringRepresentation.append(hit ?
"1" :
"0");
689 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
698 ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
699 std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
701 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
708 ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
709 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
721 objGetUTXOResponse.
pushKV(
"chainHeight", active_height);
722 objGetUTXOResponse.
pushKV(
"chaintipHash", active_hash.
GetHex());
723 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
726 for (
const CCoin &coin : outs) {
728 utxo.
pushKV(
"height", int32_t(coin.nHeight));
729 utxo.
pushKV(
"value", coin.out.nValue);
734 utxo.
pushKV(
"scriptPubKey", std::move(o));
737 objGetUTXOResponse.
pushKV(
"utxos", std::move(utxos));
740 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
741 req->
WriteHeader(
"Content-Type",
"application/json");
747 "output format not found (available: " +
755 const std::string &str_uri_part) {
759 std::string height_str;
763 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
771 if (!maybe_chainman) {
777 if (blockheight > active_chain.
Height()) {
780 pblockindex = active_chain[blockheight];
786 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
797 req->
WriteHeader(
"Content-Type",
"application/json");
805 "output format not found (available: " +
814 const std::string &strReq);
830 const std::string &
prefix) {
831 return up.handler(config, context, req,
prefix);
RPCHelpMan getblockchaininfo()
UniValue blockheaderToJSON(const CBlockIndex &tip, const CBlockIndex &blockindex)
Block header to JSON.
UniValue blockToJSON(BlockManager &blockman, const CBlock &block, const CBlockIndex &tip, const CBlockIndex &blockindex, TxVerbosity verbosity)
Block description to JSON.
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 * 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.
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.
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...
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Double ended buffer combining vector and stream-like interfaces.
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
void push_back(UniValue val)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
void pushKV(std::string key, UniValue val)
void SetHex(const char *psz)
std::string GetHex() const
CBlockIndex * LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool ReadBlock(CBlock &block, const FlatFilePos &pos) const
Functions for disk access for blocks.
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
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 TxToUniv(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, bool include_hex=true, const CTxUndo *txundo=nullptr, TxVerbosity verbosity=TxVerbosity::SHOW_DETAILS, std::function< bool(const CTxOut &)> is_change_func={})
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, BlockHash &hashBlock, const BlockManager &blockman)
Return transaction with a given txid.
Implement std::hash so RCUPtr can be used as a key for maps or sets.
std::shared_ptr< const CTransaction > CTransactionRef
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)
static bool rest_block(const Config &config, const std::any &context, HTTPRequest *req, const std::string &strURIPart, TxVerbosity tx_verbosity)
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 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 ChainstateManager * GetChainman(const std::any &context, HTTPRequest *req)
Get the node context chainstatemanager.
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 const struct @13 uri_prefixes[]
static CTxMemPool * GetMemPool(const std::any &context, HTTPRequest *req)
Get the node context mempool.
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()
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)
Returns the current warmup state.
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.
bool ParseInt32(std::string_view str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
template std::vector< std::byte > ParseHex(std::string_view)
bool IsHex(std::string_view str)
Returns true if each character in str is a hex character, and has an even number of hex digits.
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.