88 uint32_t nTxVerDummy = 0;
89 READWRITE(nTxVerDummy, obj.nHeight, obj.out);
128 if (!node_context || !node_context->mempool) {
132 return node_context->mempool.get();
145 if (!node_context || !node_context->chainman) {
149 return node_context->chainman.get();
156 param = strReq.substr(0, strReq.rfind(
'?'));
157 const std::string::size_type pos_format{param.rfind(
'.')};
160 if (pos_format == std::string::npos) {
165 const std::string suffix(param, pos_format + 1);
166 for (
const auto& rf_name :
rf_names) {
167 if (suffix == rf_name.name) {
168 param.erase(pos_format);
180 for (
const auto& rf_name :
rf_names) {
181 if (strlen(rf_name.name) > 0) {
183 formats.append(rf_name.name);
184 formats.append(
", ");
188 if (formats.length() > 0)
189 return formats.substr(0, formats.length() - 2);
196 std::string statusmessage;
204 const std::string& uri_part)
210 std::vector<std::string> path =
SplitString(param,
'/');
212 std::string raw_count;
214 if (path.size() == 2) {
218 }
else if (path.size() == 1) {
223 }
catch (
const std::runtime_error& e) {
241 std::vector<const CBlockIndex*> headers;
242 headers.reserve(*parsed_count);
244 if (!maybe_chainman)
return false;
249 tip = active_chain.
Tip();
251 while (pindex !=
nullptr && active_chain.
Contains(*pindex)) {
252 headers.push_back(pindex);
253 if (headers.size() == *parsed_count) {
256 pindex = active_chain.
Next(*pindex);
264 ssHeader << pindex->GetBlockHeader();
277 ssHeader << pindex->GetBlockHeader();
280 std::string strHex =
HexStr(ssHeader) +
"\n";
291 std::string strJSON = jsonHeaders.
write() +
"\n";
313 coin.
out.Serialize(stream);
332 prevout.
pushKV(
"scriptPubKey", std::move(script_pub_key));
334 tx_prevouts.
push_back(std::move(prevout));
336 result.
push_back(std::move(tx_prevouts));
347 std::vector<std::string> path =
SplitString(param,
'/');
350 if (path.size() == 1) {
390 const std::string strHex{
HexStr(ssSpentResponse) +
"\n"};
400 std::string strJSON = result.
write() +
"\n";
421 const std::string& uri_part,
422 std::optional<TxVerbosity> tx_verbosity,
423 std::optional<std::pair<size_t, size_t>> block_part = std::nullopt)
439 if (!maybe_chainman)
return false;
449 if (chainman.
m_blockman.IsBlockPruned(*pblockindex)) {
459 switch (block_data.error()) {
477 const std::string strHex{
HexStr(*block_data) +
"\n"};
489 std::string strJSON = objBlock.
write() +
"\n";
521 {{*opt_offset, *opt_size}});
528 }
catch (
const std::runtime_error& e) {
540 std::vector<std::string> uri_parts =
SplitString(param,
'/');
541 std::string raw_count;
542 std::string raw_blockhash;
543 if (uri_parts.size() == 3) {
545 raw_blockhash = uri_parts[2];
546 raw_count = uri_parts[1];
547 }
else if (uri_parts.size() == 2) {
549 raw_blockhash = uri_parts[1];
552 }
catch (
const std::runtime_error& e) {
556 return RESTERR(
req,
HTTP_BAD_REQUEST,
"Invalid URI format. Expected /rest/blockfilterheaders/<filtertype>/<blockhash>.<ext>?count=<count>");
579 std::vector<const CBlockIndex*> headers;
580 headers.reserve(*parsed_count);
583 if (!maybe_chainman)
return false;
588 while (pindex !=
nullptr && active_chain.
Contains(*pindex)) {
589 headers.push_back(pindex);
590 if (headers.size() == *parsed_count)
592 pindex = active_chain.
Next(*pindex);
596 bool index_ready = index->BlockUntilSyncedToCurrentChain();
598 std::vector<uint256> filter_headers;
599 filter_headers.reserve(*parsed_count);
603 std::string errmsg =
"Filter not found.";
606 errmsg +=
" Block filters are still in the process of being indexed.";
608 errmsg +=
" This error is unexpected and indicates index corruption.";
613 filter_headers.push_back(filter_header);
619 for (
const uint256& header : filter_headers) {
631 for (
const uint256& header : filter_headers) {
635 std::string strHex =
HexStr(ssHeader) +
"\n";
643 for (
const uint256& header : filter_headers) {
647 std::string strJSON = jsonHeaders.
write() +
"\n";
667 std::vector<std::string> uri_parts =
SplitString(param,
'/');
668 if (uri_parts.size() != 2) {
688 bool block_was_connected;
691 if (!maybe_chainman)
return false;
701 bool index_ready = index->BlockUntilSyncedToCurrentChain();
705 std::string errmsg =
"Filter not found.";
707 if (!block_was_connected) {
708 errmsg +=
" Block was not connected to active chain.";
709 }
else if (!index_ready) {
710 errmsg +=
" Block filters are still in the process of being indexed.";
712 errmsg +=
" This error is unexpected and indicates index corruption.";
732 std::string strHex =
HexStr(ssResp) +
"\n";
741 std::string strJSON =
ret.write() +
"\n";
769 std::string strJSON = chainInfoObject.
write() +
"\n";
788 std::string hash_str;
790 const bool current_tip{hash_str.empty()};
805 if (!chainman)
return false;
832 if (param !=
"contents" && param !=
"info") {
837 if (!mempool)
return false;
841 std::string str_json;
842 if (param ==
"contents") {
843 std::string raw_verbose;
846 }
catch (
const std::runtime_error& e) {
849 if (raw_verbose !=
"true" && raw_verbose !=
"false") {
852 std::string raw_mempool_sequence;
855 }
catch (
const std::runtime_error& e) {
858 if (raw_mempool_sequence !=
"true" && raw_mempool_sequence !=
"false") {
861 const bool verbose{raw_verbose ==
"true"};
862 const bool mempool_sequence{raw_mempool_sequence ==
"true"};
863 if (verbose && mempool_sequence) {
864 return RESTERR(
req,
HTTP_BAD_REQUEST,
"Verbose results cannot contain mempool sequence values. (hint: set \"verbose=false\")");
895 g_txindex->BlockUntilSyncedToCurrentChain();
899 if (!
node)
return false;
920 std::string strHex =
HexStr(ssTx) +
"\n";
930 std::string strJSON = objTx.
write() +
"\n";
950 std::vector<std::string> uriParts;
951 if (param.length() > 1)
953 std::string strUriParams = param.substr(1);
959 if (strRequestMutable.length() == 0 && uriParts.size() == 0)
962 bool fInputParsed =
false;
963 bool fCheckMemPool =
false;
964 std::vector<COutPoint> vOutPoints;
969 if (uriParts.size() > 0)
972 if (uriParts[0] ==
"checkmempool") fCheckMemPool =
true;
974 for (
size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
977 if (txid_out.size() != 2) {
983 if (!txid || !output) {
987 vOutPoints.emplace_back(*txid, *output);
990 if (vOutPoints.size() > 0)
999 std::vector<unsigned char> strRequestV =
ParseHex(strRequestMutable);
1000 strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
1007 if (strRequestMutable.size() > 0)
1013 oss << strRequestMutable;
1014 oss >> fCheckMemPool;
1017 }
catch (
const std::ios_base::failure&) {
1039 std::vector<unsigned char> bitmap;
1040 std::vector<CCoin> outs;
1041 std::string bitmapStringRepresentation;
1042 std::vector<bool> hits;
1043 bitmap.resize(
CeilDiv(vOutPoints.size(), 8u));
1045 if (!maybe_chainman)
return false;
1051 for (
const COutPoint& vOutPoint : vOutPoints) {
1052 auto coin = !mempool || !mempool->isSpent(vOutPoint) ? view.GetCoin(vOutPoint) : std::nullopt;
1053 hits.push_back(coin.has_value());
1054 if (coin) outs.emplace_back(std::move(*coin));
1060 if (fCheckMemPool) {
1062 if (!mempool)
return false;
1067 process_utxos(viewMempool, mempool);
1073 for (
size_t i = 0; i < hits.size(); ++i) {
1074 const bool hit = hits[i];
1075 bitmapStringRepresentation.append(hit ?
"1" :
"0");
1076 bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
1085 ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
1095 ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
1096 std::string strHex =
HexStr(ssGetUTXOResponse) +
"\n";
1109 objGetUTXOResponse.
pushKV(
"chainHeight", active_height);
1110 objGetUTXOResponse.
pushKV(
"chaintipHash", active_hash.
GetHex());
1111 objGetUTXOResponse.
pushKV(
"bitmap", bitmapStringRepresentation);
1114 for (
const CCoin& coin : outs) {
1116 utxo.
pushKV(
"height", coin.nHeight);
1122 utxo.
pushKV(
"scriptPubKey", std::move(o));
1125 objGetUTXOResponse.
pushKV(
"utxos", std::move(utxos));
1128 std::string strJSON = objGetUTXOResponse.
write() +
"\n";
1141 const std::string& str_uri_part)
1144 std::string height_str;
1148 if (!blockheight || *blockheight < 0) {
1155 if (!maybe_chainman)
return false;
1159 if (*blockheight > active_chain.
Height()) {
1162 pblockindex = active_chain[*blockheight];
1194static const struct {
1217 auto handler = [context, up](
HTTPRequest*
req,
const std::string& prefix) {
return up.handler(context,
req, prefix); };
std::vector< std::string > SplitString(std::string_view str, char sep)
UniValue blockToJSON(BlockManager &blockman, const CBlock &block, const CBlockIndex &tip, const CBlockIndex &blockindex, TxVerbosity verbosity, const uint256 pow_limit)
Block description to JSON.
UniValue blockheaderToJSON(const CBlockIndex &tip, const CBlockIndex &blockindex, const uint256 pow_limit)
Block header to JSON.
bool BlockFilterTypeByName(std::string_view name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
@ BLOCK_HAVE_DATA
full block available in blk*.dat
#define STR_INTERNAL_BUG(msg)
Complete block filter struct as defined in BIP 157.
const std::vector< unsigned char > & GetEncodedFilter() const LIFETIMEBOUND
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
bool LookupFilter(const CBlockIndex *block_index, BlockFilter &filter_out) const
Get a single filter by block.
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache)
Get a single filter header by block.
The block chain is a tree shaped structure starting with the genesis block at the root,...
bool IsValid(enum BlockStatus nUpTo) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
uint256 GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
Undo information for a CBlock.
std::vector< CTxUndo > vtxundo
An in-memory indexed chain of blocks.
bool Contains(const CBlockIndex &index) const
Efficiently check whether a block is present in this chain.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockIndex * Next(const CBlockIndex &index) 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.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Pure abstract view on the open txout dataset.
CCoinsView that brings transactions from a mempool into view.
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 ...
An output of a transaction.
Undo information for a CTransaction.
std::vector< Coin > vprevout
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Chainstate & ActiveChainstate() const
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
const Consensus::Params & GetConsensus() const
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
node::BlockManager m_blockman
CTxOut out
unspent transaction output
Double ended buffer combining vector and stream-like interfaces.
void WriteHeader(std::string &&hdr, std::string &&value)
std::optional< std::string > GetQueryParameter(std::string_view key) const
std::string ReadBody() const
void WriteReply(HTTPStatusCode status, std::span< const std::byte > reply_body={})
UniValue HandleRequest(const JSONRPCRequest &request) const
Minimal stream for reading from an existing byte array by std::span.
void push_back(UniValue val)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
void pushKV(std::string key, UniValue val)
std::string GetHex() const
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool ReadBlockUndo(CBlockUndo &blockundo, const CBlockIndex &index) const
ReadRawBlockResult ReadRawBlock(const FlatFilePos &pos, std::optional< std::pair< size_t, size_t > > block_part=std::nullopt) const
static std::optional< transaction_identifier > FromHex(std::string_view hex)
constexpr uint256()=default
static std::optional< uint256 > FromHex(std::string_view str)
void ScriptToUniv(const CScript &script, UniValue &out, bool include_hex, bool include_address, const SigningProvider *provider)
void TxToUniv(const CTransaction &tx, const uint256 &block_hash, UniValue &entry, bool include_hex, const CTxUndo *txundo, TxVerbosity verbosity, std::function< bool(const CTxOut &)> is_change_func)
UniValue ValueFromAmount(const CAmount amount)
@ SHOW_DETAILS_AND_PREVOUT
The same as previous option with information about prevouts if available.
@ SHOW_TXID
Only TXID for each block's transaction.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
void StartREST(const std::any &context)
Start HTTP REST subsystem.
void StopREST()
Stop HTTP REST subsystem.
void InterruptREST()
Interrupt RPC REST subsystem.
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 &hash, const BlockManager &blockman, uint256 &hashBlock)
Return transaction with a given hash.
std::vector< std::string > SplitString(std::string_view str, char sep)
std::vector< T > Split(std::span< const char > sp LIFETIMEBOUND, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
T * AnyPtr(const std::any &any) noexcept
Helper function to access the contained object of a std::any instance.
constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
Integer ceiling division (for unsigned values).
constexpr TransactionSerParams TX_WITH_WITNESS
std::shared_ptr< const CTransaction > CTransactionRef
static constexpr unsigned int MAX_REST_HEADERS_RESULTS
static bool rest_headers(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static void SerializeBlockUndo(DataStream &stream, const CBlockUndo &block_undo)
Serialize spent outputs as a list of per-transaction CTxOut lists using binary format.
static bool rest_block_extended(const std::any &context, HTTPRequest *req, const std::string &uri_part)
CTransactionRef GetTransaction(const CBlockIndex *block_index, const CTxMemPool *mempool, const Txid &hash, const BlockManager &blockman, uint256 &hashBlock)
Return transaction with a given hash.
static bool rest_blockhash_by_height(const std::any &context, HTTPRequest *req, const std::string &str_uri_part)
static bool rest_block_part(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static const struct @241067227063174173171120277006046215202134064040 uri_prefixes[]
static constexpr const char * REST_CACHE_IMMUTABLE
Response bytes never change.
static bool rest_block_filter(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static bool rest_block_notxdetails(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static bool rest_filter_header(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static bool rest_getutxos(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static bool rest_tx(const std::any &context, HTTPRequest *req, const std::string &uri_part)
static bool rest_block(const std::any &context, HTTPRequest *req, const std::string &uri_part, std::optional< TxVerbosity > tx_verbosity, std::optional< std::pair< size_t, size_t > > block_part=std::nullopt)
This handler is used by multiple HTTP endpoints:
static const struct @100340210357045130265072364121206334104121063345 rf_names[]
static bool rest_deploymentinfo(const std::any &context, HTTPRequest *req, const std::string &str_uri_part)
static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status, std::string message)
static bool rest_mempool(const std::any &context, HTTPRequest *req, const std::string &str_uri_part)
static constexpr const char * REST_CACHE_NO_STORE
Mutable, node-local, or error response; must not be cached.
static bool CheckWarmup(HTTPRequest *req)
static ChainstateManager * GetChainman(const std::any &context, HTTPRequest *req)
Get the node context chainstatemanager.
RPCMethod getblockchaininfo()
static void BlockUndoToJSON(const CBlockUndo &block_undo, UniValue &result)
Serialize spent outputs as a list of per-transaction CTxOut lists using JSON format.
static bool rest_chaininfo(const std::any &context, HTTPRequest *req, const std::string &uri_part)
RPCMethod getdeploymentinfo()
static bool rest_spent_txouts(const std::any &context, HTTPRequest *req, const std::string &uri_part)
RESTResponseFormat ParseDataFormat(std::string ¶m, const std::string &strReq)
Parse a URI to get the data format and URI without data format and query string.
static CTxMemPool * GetMemPool(const std::any &context, HTTPRequest *req)
Get the node context mempool.
static const size_t MAX_GETUTXOS_OUTPOINTS
static std::string AvailableDataFormatsString()
static NodeContext * GetNodeContext(const std::any &context, HTTPRequest *req)
Get the node context.
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
HTTPStatusCode
HTTP status codes.
@ HTTP_SERVICE_UNAVAILABLE
@ HTTP_INTERNAL_SERVER_ERROR
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
bool RPCIsInWarmup(std::string *outStatus)
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::optional< T > ToIntegral(std::string_view str, size_t base=10)
Convert string to integral type T.
@ SAFE_CHARS_URI
Chars allowed in URIs (RFC 3986).
bool(*) handler(const std::any &context, HTTPRequest *req, const std::string &strReq)
SERIALIZE_METHODS(CCoin, obj)
uint256 powLimit
Proof of work parameters.
#define WITH_LOCK(cs, code)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.