27 #include <boost/algorithm/string.hpp> 57 : nHeight(in.GetHeight()), out(
std::move(in.GetTxOut())) {}
61 template <
typename Stream,
typename Operation>
63 uint32_t nTxVerDummy = 0;
71 std::string message) {
97 const std::string &strReq) {
98 const std::string::size_type pos = strReq.rfind(
'.');
99 if (pos == std::string::npos) {
104 param = strReq.substr(0, pos);
105 const std::string suff(strReq, pos + 1);
124 formats.append(
", ");
128 if (formats.length() > 0) {
129 return formats.substr(0, formats.length() - 2);
136 std::string statusmessage;
139 "Service temporarily unavailable: " + statusmessage);
153 std::vector<std::string> path;
154 boost::split(path, param, boost::is_any_of(
"/"));
156 if (path.size() != 2) {
158 "No header count specified. Use " 159 "/rest/headers/<count>/<hash>.<ext>.");
162 long count = strtol(path[0].c_str(),
nullptr, 10);
163 if (count < 1 || count > 2000) {
165 "Header count out of range: " + path[0]);
168 std::string hashStr = path[1];
177 std::vector<const CBlockIndex *> headers;
178 headers.reserve(count);
183 while (pindex !=
nullptr && ::
ChainActive().Contains(pindex)) {
184 headers.push_back(pindex);
185 if (headers.size() == size_t(count)) {
196 ssHeader << pindex->GetBlockHeader();
199 std::string binaryHeader = ssHeader.
str();
200 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
208 ssHeader << pindex->GetBlockHeader();
222 std::string strJSON = jsonHeaders.
write() +
"\n";
223 req->
WriteHeader(
"Content-Type",
"application/json");
229 "output format not found (available: .bin, .hex)");
235 const std::string &strURIPart,
bool showTxDetails) {
263 hashStr +
" not available (pruned data)");
277 std::string binaryBlock = ssBlock.
str();
278 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
287 std::string strHex =
HexStr(ssBlock.
begin(), ssBlock.
end()) +
"\n";
295 blockToJSON(block, tip, pblockindex, showTxDetails);
296 std::string strJSON = objBlock.
write() +
"\n";
297 req->
WriteHeader(
"Content-Type",
"application/json");
304 "output format not found (available: " +
312 const std::string &strURIPart) {
313 return rest_block(config, req, strURIPart,
true);
318 const std::string &strURIPart) {
319 return rest_block(config, req, strURIPart,
false);
336 std::string strJSON = chainInfoObject.
write() +
"\n";
337 req->
WriteHeader(
"Content-Type",
"application/json");
343 "output format not found (available: json)");
366 std::string strJSON = mempoolInfoObject.
write() +
"\n";
367 req->
WriteHeader(
"Content-Type",
"application/json");
373 "output format not found (available: json)");
380 const std::string &strURIPart) {
397 std::string strJSON = mempoolObject.
write() +
"\n";
398 req->
WriteHeader(
"Content-Type",
"application/json");
404 "output format not found (available: json)");
410 const std::string &strURIPart) {
423 const TxId txid(hash);
426 g_txindex->BlockUntilSyncedToCurrentChain();
442 std::string binaryTx = ssTx.
str();
443 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
462 std::string strJSON = objTx.
write() +
"\n";
463 req->
WriteHeader(
"Content-Type",
"application/json");
470 "output format not found (available: " +
485 std::vector<std::string> uriParts;
486 if (param.length() > 1) {
487 std::string strUriParams = param.substr(1);
488 boost::split(uriParts, strUriParams, boost::is_any_of(
"/"));
492 std::string strRequestMutable = req->
ReadBody();
493 if (strRequestMutable.length() == 0 && uriParts.size() == 0) {
497 bool fInputParsed =
false;
498 bool fCheckMemPool =
false;
499 std::vector<COutPoint> vOutPoints;
505 if (uriParts.size() > 0) {
508 if (uriParts[0] ==
"checkmempool") {
509 fCheckMemPool =
true;
512 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++) {
514 std::string strTxid = uriParts[i].substr(0, uriParts[i].find(
'-'));
515 std::string strOutput =
516 uriParts[i].substr(uriParts[i].find(
'-') + 1);
524 vOutPoints.push_back(
COutPoint(txid, uint32_t(nOutput)));
527 if (vOutPoints.size() > 0) {
537 std::vector<uint8_t> strRequestV =
ParseHex(strRequestMutable);
538 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
544 if (strRequestMutable.size() > 0) {
548 "Combination of URI scheme inputs and " 549 "raw post data is not allowed");
553 oss << strRequestMutable;
554 oss >> fCheckMemPool;
557 }
catch (
const std::ios_base::failure &) {
572 "output format not found (available: " +
581 strprintf(
"Error: max outpoints exceeded (max: %d, tried: %d)",
587 std::vector<uint8_t> bitmap;
588 std::vector<CCoin> outs;
589 std::string bitmapStringRepresentation;
590 std::vector<bool> hits;
591 bitmap.resize((vOutPoints.size() + 7) / 8);
593 auto process_utxos = [&vOutPoints, &outs,
596 for (
const COutPoint &vOutPoint : vOutPoints) {
598 bool hit = !mempool.isSpent(vOutPoint) &&
599 view.GetCoin(vOutPoint, coin);
602 outs.emplace_back(std::move(coin));
618 process_utxos(viewMempool, *mempool);
625 for (
size_t i = 0; i < hits.size(); ++i) {
626 const bool hit = hits[i];
629 bitmapStringRepresentation.append(hit ?
"1" :
"0");
630 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
642 std::string ssGetUTXOResponseString = ssGetUTXOResponse.
str();
644 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
669 objGetUTXOResponse.
pushKV(
670 "chaintipHash", ::
ChainActive().Tip()->GetBlockHash().GetHex());
671 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
674 for (
const CCoin &coin : outs) {
676 utxo.
pushKV(
"height", int32_t(coin.nHeight));
682 utxo.
pushKV(
"scriptPubKey", o);
685 objGetUTXOResponse.
pushKV(
"utxos", utxos);
688 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
689 req->
WriteHeader(
"Content-Type",
"application/json");
695 "output format not found (available: " +
703 const std::string &str_uri_part) {
707 std::string height_str;
711 if (!
ParseInt32(height_str, &blockheight) || blockheight < 0) {
728 req->
WriteHeader(
"Content-Type",
"application/octet-stream");
739 req->
WriteHeader(
"Content-Type",
"application/json");
747 "output format not found (available: " +
753 static const struct {
756 const std::string &strReq);
772 const std::string &
prefix) {
773 return up.handler(config, context, req,
prefix);
std::shared_ptr< const CTransaction > CTransactionRef
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
static bool rest_blockhash_by_height(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &str_uri_part)
static bool CheckWarmup(HTTPRequest *req)
static bool rest_mempool_contents(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params ¶ms)
Functions for disk access for blocks.
static bool rest_block_extended(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static RetFormat ParseDataFormat(std::string ¶m, const std::string &strReq)
static std::string AvailableDataFormatsString()
static bool rest_mempool_info(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
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.
Double ended buffer combining vector and stream-like interfaces.
virtual const CChainParams & GetChainParams() const =0
void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
Register handler for prefix.
CChainState & ChainstateActive()
BlockHash GetBlockHash() const
bool GetTransaction(const TxId &txid, CTransactionRef &txOut, const Consensus::Params ¶ms, BlockHash &hashBlock, const CBlockIndex *const block_index)
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock...
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.
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 IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
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)
Returns true if each character in str is a hex character, and has an even number of hex digits...
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
Unregister handler for prefix.
RecursiveMutex cs_main
Global state.
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
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 CTxMemPool * GetMemPool(const util::Ref &context, HTTPRequest *req)
Get the node context mempool.
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
Block description to JSON.
Type-safe dynamic reference.
static bool rest_tx(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
bool(* handler)(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strReq)
static bool rest_chaininfo(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static const size_t MAX_GETUTXOS_OUTPOINTS
static const struct @15 rf_names[]
const_iterator end() const
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
static bool rest_getutxos(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
const_iterator begin() const
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
A BlockHash is a unqiue identifier for a block.
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...
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
A TxId is the identifier of a transaction.
static const int PROTOCOL_VERSION
network protocol versioning
std::vector< uint8_t > ParseHex(const char *psz)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockIndex * LookupBlockIndex(const BlockHash &hash)
std::string GetHex() const
std::string HexStr(const T itbegin, const T itend)
bool RPCIsInWarmup(std::string *outStatus)
Returns the current warmup state.
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
static bool rest_block(const Config &config, HTTPRequest *req, const std::string &strURIPart, bool showTxDetails)
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::string ReadBody()
Read request body.
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
static bool rest_headers(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
static bool rest_block_notxdetails(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strURIPart)
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
static const struct @16 uri_prefixes[]
UniValue getblockchaininfo(const Config &config, const JSONRPCRequest &request)
void SerializationOp(Stream &s, Operation ser_action)
const Consensus::Params & GetConsensus() const
void InterruptREST()
Interrupt RPC REST subsystem.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
void SetHex(const char *psz)
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose)
Mempool to JSON.
CCoinsView that brings transactions from a mempool into view.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
void StartREST(const util::Ref &context)
Start HTTP REST subsystem.
UniValue ValueFromAmount(const Amount &amount)