61 :
nHeight(in.GetHeight()),
out(std::move(in.GetTxOut())) {}
64 uint32_t nTxVerDummy = 0;
65 READWRITE(nTxVerDummy, obj.nHeight, obj.out);
70 std::string message) {
84 auto node_context = util::AnyPtr<NodeContext>(context);
88 "Internal bug detected: Node context not found!\n"
89 "You may report this issue here: %s\n",
90 __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
104 auto node_context = util::AnyPtr<NodeContext>(context);
105 if (!node_context || !node_context->mempool) {
109 return node_context->mempool.get();
121 auto node_context = util::AnyPtr<NodeContext>(context);
122 if (!node_context || !node_context->chainman) {
125 "Internal bug detected: Chainman disabled or instance"
127 "You may report this issue here: %s\n",
128 __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
131 return node_context->chainman.get();
135 const std::string &strReq) {
136 const std::string::size_type pos = strReq.rfind(
'.');
137 if (pos == std::string::npos) {
142 param = strReq.substr(0, pos);
143 const std::string suff(strReq, pos + 1);
145 for (
const auto &rf_name :
rf_names) {
146 if (suff == rf_name.name) {
158 for (
const auto &rf_name :
rf_names) {
159 if (strlen(rf_name.name) > 0) {
161 formats.append(rf_name.name);
162 formats.append(
", ");
166 if (formats.length() > 0) {
167 return formats.substr(0, formats.length() - 2);
174 std::string statusmessage;
177 "Service temporarily unavailable: " + statusmessage);
191 std::vector<std::string> path =
SplitString(param,
'/');
193 if (path.size() != 2) {
195 "No header count specified. Use "
196 "/rest/headers/<count>/<hash>.<ext>.");
199 long count = strtol(path[0].c_str(),
nullptr, 10);
200 if (count < 1 || count > 2000) {
202 "Header count out of range: " + path[0]);
205 std::string hashStr = path[1];
214 std::vector<const CBlockIndex *> headers;
215 headers.reserve(
count);
218 if (!maybe_chainman) {
224 tip = active_chain.
Tip();
226 while (pindex !=
nullptr && active_chain.
Contains(pindex)) {
227 headers.push_back(pindex);
228 if (headers.size() ==
size_t(
count)) {
231 pindex = active_chain.
Next(pindex);
239 ssHeader << pindex->GetBlockHeader();
242 std::string binaryHeader = ssHeader.
str();
243 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
251 ssHeader << pindex->GetBlockHeader();
254 std::string strHex =
HexStr(ssHeader) +
"\n";
264 std::string strJSON = jsonHeaders.
write() +
"\n";
265 req->
WriteHeader(
"Content-Type",
"application/json");
272 "output format not found (available: .bin, .hex, .json)");
279 bool showTxDetails) {
298 if (!maybe_chainman) {
310 if (chainman.
m_blockman.IsBlockPruned(pblockindex)) {
312 hashStr +
" not available (pruned data)");
325 std::string binaryBlock = ssBlock.
str();
326 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
335 std::string strHex =
HexStr(ssBlock) +
"\n";
343 pblockindex, showTxDetails);
344 std::string strJSON = objBlock.
write() +
"\n";
345 req->
WriteHeader(
"Content-Type",
"application/json");
352 "output format not found (available: " +
360 const std::string &strURIPart) {
361 return rest_block(config, context, req, strURIPart,
true);
366 const std::string &strURIPart) {
367 return rest_block(config, context, req, strURIPart,
false);
386 std::string strJSON = chainInfoObject.
write() +
"\n";
387 req->
WriteHeader(
"Content-Type",
"application/json");
393 "output format not found (available: json)");
416 std::string strJSON = mempoolInfoObject.
write() +
"\n";
417 req->
WriteHeader(
"Content-Type",
"application/json");
423 "output format not found (available: json)");
430 const std::string &strURIPart) {
447 std::string strJSON = mempoolObject.
write() +
"\n";
448 req->
WriteHeader(
"Content-Type",
"application/json");
454 "output format not found (available: json)");
460 const std::string &strURIPart) {
473 const TxId txid(hash);
476 g_txindex->BlockUntilSyncedToCurrentChain();
486 Params().GetConsensus(), hashBlock);
497 std::string binaryTx = ssTx.
str();
498 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
508 std::string strHex =
HexStr(ssTx) +
"\n";
517 std::string strJSON = objTx.
write() +
"\n";
518 req->
WriteHeader(
"Content-Type",
"application/json");
525 "output format not found (available: " +
540 std::vector<std::string> uriParts;
541 if (param.length() > 1) {
542 std::string strUriParams = param.substr(1);
547 std::string strRequestMutable = req->
ReadBody();
548 if (strRequestMutable.length() == 0 && uriParts.size() == 0) {
552 bool fInputParsed =
false;
553 bool fCheckMemPool =
false;
554 std::vector<COutPoint> vOutPoints;
560 if (uriParts.size() > 0) {
563 if (uriParts[0] ==
"checkmempool") {
564 fCheckMemPool =
true;
567 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++) {
569 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
570 std::string strOutput =
571 uriParts[i].substr(uriParts[i].find(
'-') + 1);
579 vOutPoints.push_back(
COutPoint(txid, uint32_t(nOutput)));
582 if (vOutPoints.size() > 0) {
592 std::vector<uint8_t> strRequestV =
ParseHex(strRequestMutable);
593 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
599 if (strRequestMutable.size() > 0) {
603 "Combination of URI scheme inputs and "
604 "raw post data is not allowed");
608 oss << strRequestMutable;
609 oss >> fCheckMemPool;
612 }
catch (
const std::ios_base::failure &) {
627 "output format not found (available: " +
636 strprintf(
"Error: max outpoints exceeded (max: %d, tried: %d)",
642 std::vector<uint8_t> bitmap;
643 std::vector<CCoin> outs;
644 std::string bitmapStringRepresentation;
645 std::vector<bool> hits;
646 bitmap.resize((vOutPoints.size() + 7) / 8);
648 if (!maybe_chainman) {
653 auto process_utxos = [&vOutPoints, &outs,
656 for (
const COutPoint &vOutPoint : vOutPoints) {
658 bool hit = !mempool.isSpent(vOutPoint) &&
659 view.GetCoin(vOutPoint, coin);
662 outs.emplace_back(std::move(coin));
678 process_utxos(viewMempool, *mempool);
685 for (
size_t i = 0; i < hits.size(); ++i) {
686 const bool hit = hits[i];
689 bitmapStringRepresentation.append(hit ?
"1" :
"0");
690 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
702 std::string ssGetUTXOResponseString = ssGetUTXOResponse.
str();
704 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
714 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
727 objGetUTXOResponse.
pushKV(
729 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
732 for (
const CCoin &coin : outs) {
734 utxo.
pushKV(
"height", int32_t(coin.nHeight));
735 utxo.
pushKV(
"value", coin.out.nValue);
740 utxo.
pushKV(
"scriptPubKey", o);
743 objGetUTXOResponse.
pushKV(
"utxos", utxos);
746 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
747 req->
WriteHeader(
"Content-Type",
"application/json");
753 "output format not found (available: " +
761 const std::string &str_uri_part) {
765 std::string height_str;
769 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
777 if (!maybe_chainman) {
783 if (blockheight > active_chain.
Height()) {
786 pblockindex = active_chain[blockheight];
792 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
803 req->
WriteHeader(
"Content-Type",
"application/json");
811 "output format not found (available: " +
817 static const struct {
820 const std::string &strReq);
836 const std::string &
prefix) {
837 return up.handler(config, context, req,
prefix);
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
RPCHelpMan getblockchaininfo()
UniValue blockToJSON(BlockManager &blockman, const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
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
Global state.
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.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Chainstate & ActiveChainstate() const
The most-work chain.
CBlockIndex * ActiveTip() const
CChain & ActiveChain() const
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.
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 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.
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.
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
static const int PROTOCOL_VERSION
network protocol versioning