|
|
|
@ -8,6 +8,7 @@
|
|
|
|
|
#include <core_io.h>
|
|
|
|
|
#include <httpserver.h>
|
|
|
|
|
#include <index/txindex.h>
|
|
|
|
|
#include <node/context.h>
|
|
|
|
|
#include <primitives/block.h>
|
|
|
|
|
#include <primitives/transaction.h>
|
|
|
|
|
#include <rpc/blockchain.h>
|
|
|
|
@ -16,6 +17,7 @@
|
|
|
|
|
#include <streams.h>
|
|
|
|
|
#include <sync.h>
|
|
|
|
|
#include <txmempool.h>
|
|
|
|
|
#include <util/check.h>
|
|
|
|
|
#include <util/strencodings.h>
|
|
|
|
|
#include <validation.h>
|
|
|
|
|
#include <version.h>
|
|
|
|
@ -69,6 +71,24 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the node context mempool.
|
|
|
|
|
*
|
|
|
|
|
* Set the HTTP error and return nullptr if node context
|
|
|
|
|
* mempool is not found.
|
|
|
|
|
*
|
|
|
|
|
* @param[in] req the HTTP request
|
|
|
|
|
* return pointer to the mempool or nullptr if no mempool found
|
|
|
|
|
*/
|
|
|
|
|
static CTxMemPool* GetMemPool(HTTPRequest* req)
|
|
|
|
|
{
|
|
|
|
|
if (!g_rpc_node || !g_rpc_node->mempool) {
|
|
|
|
|
RESTERR(req, HTTP_NOT_FOUND, "Mempool disabled or instance not found");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return g_rpc_node->mempool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static RetFormat ParseDataFormat(std::string& param, const std::string& strReq)
|
|
|
|
|
{
|
|
|
|
|
const std::string::size_type pos = strReq.rfind('.');
|
|
|
|
@ -295,12 +315,14 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
|
|
|
|
|
{
|
|
|
|
|
if (!CheckWarmup(req))
|
|
|
|
|
return false;
|
|
|
|
|
const CTxMemPool* mempool = GetMemPool(req);
|
|
|
|
|
if (!mempool) return false;
|
|
|
|
|
std::string param;
|
|
|
|
|
const RetFormat rf = ParseDataFormat(param, strURIPart);
|
|
|
|
|
|
|
|
|
|
switch (rf) {
|
|
|
|
|
case RetFormat::JSON: {
|
|
|
|
|
UniValue mempoolInfoObject = MempoolInfoToJSON(::mempool);
|
|
|
|
|
UniValue mempoolInfoObject = MempoolInfoToJSON(*mempool);
|
|
|
|
|
|
|
|
|
|
std::string strJSON = mempoolInfoObject.write() + "\n";
|
|
|
|
|
req->WriteHeader("Content-Type", "application/json");
|
|
|
|
@ -315,14 +337,15 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
|
|
|
|
|
|
|
|
|
|
static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
|
|
|
|
|
{
|
|
|
|
|
if (!CheckWarmup(req))
|
|
|
|
|
return false;
|
|
|
|
|
if (!CheckWarmup(req)) return false;
|
|
|
|
|
const CTxMemPool* mempool = GetMemPool(req);
|
|
|
|
|
if (!mempool) return false;
|
|
|
|
|
std::string param;
|
|
|
|
|
const RetFormat rf = ParseDataFormat(param, strURIPart);
|
|
|
|
|
|
|
|
|
|
switch (rf) {
|
|
|
|
|
case RetFormat::JSON: {
|
|
|
|
|
UniValue mempoolObject = MempoolToJSON(::mempool, true);
|
|
|
|
|
UniValue mempoolObject = MempoolToJSON(*mempool, true);
|
|
|
|
|
|
|
|
|
|
std::string strJSON = mempoolObject.write() + "\n";
|
|
|
|
|
req->WriteHeader("Content-Type", "application/json");
|
|
|
|
@ -500,11 +523,13 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (fCheckMemPool) {
|
|
|
|
|
const CTxMemPool* mempool = GetMemPool(req);
|
|
|
|
|
if (!mempool) return false;
|
|
|
|
|
// use db+mempool as cache backend in case user likes to query mempool
|
|
|
|
|
LOCK2(cs_main, mempool.cs);
|
|
|
|
|
LOCK2(cs_main, mempool->cs);
|
|
|
|
|
CCoinsViewCache& viewChain = ::ChainstateActive().CoinsTip();
|
|
|
|
|
CCoinsViewMemPool viewMempool(&viewChain, mempool);
|
|
|
|
|
process_utxos(viewMempool, mempool);
|
|
|
|
|
CCoinsViewMemPool viewMempool(&viewChain, *mempool);
|
|
|
|
|
process_utxos(viewMempool, *mempool);
|
|
|
|
|
} else {
|
|
|
|
|
LOCK(cs_main); // no need to lock mempool!
|
|
|
|
|
process_utxos(::ChainstateActive().CoinsTip(), CTxMemPool());
|
|
|
|
|