mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
Merge #18740: Remove g_rpc_node global
b3f7f375efrefactor: Remove g_rpc_node global (Russell Yanofsky)ccb5059ee8scripted-diff: Remove g_rpc_node references (Russell Yanofsky)6fca33b2edrefactor: Pass NodeContext to RPC and REST methods through util::Ref (Russell Yanofsky)691c817b34Add util::Ref class as temporary alternative for c++17 std::any (Russell Yanofsky) Pull request description: This PR removes the `g_rpc_node` global, to get same benefits we see removing other globals and make RPC code more testable, modular, and reusable. This uses a hybrid of the approaches suggested in #17548. Instead of using `std::any`, which isn't available in c++11, or `void*`, which isn't type safe, it uses a small new `util::Ref` helper class, which acts like a simplified `std::any` that only holds references, not values. Motivation for writing this was to provide an simpler alternative to #18647 by Harris Brakmić (brakmic) which avoids some shortcomings of that PR (https://github.com/bitcoin/bitcoin/pull/18647#issuecomment-617878826) ACKs for top commit: MarcoFalke: re-ACKb3f7f375ef, only change is adding back const and more tests 🚾 ajtowns: ACKb3f7f375efTree-SHA512: 56292268a001bdbe34d641db1180c215351503966ff451e55cc96c9137f1d262225d7d7733de9c9da7ce7d7a4b34213a98c2476266b58c89dbbb0f3cb5aa5d70
This commit is contained in:
45
src/rest.cpp
45
src/rest.cpp
@@ -18,6 +18,7 @@
|
||||
#include <sync.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/check.h>
|
||||
#include <util/ref.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <validation.h>
|
||||
#include <version.h>
|
||||
@@ -75,13 +76,14 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me
|
||||
* @param[in] req the HTTP request
|
||||
* return pointer to the mempool or nullptr if no mempool found
|
||||
*/
|
||||
static CTxMemPool* GetMemPool(HTTPRequest* req)
|
||||
static CTxMemPool* GetMemPool(const util::Ref& context, HTTPRequest* req)
|
||||
{
|
||||
if (!g_rpc_node || !g_rpc_node->mempool) {
|
||||
NodeContext* node = context.Has<NodeContext>() ? &context.Get<NodeContext>() : nullptr;
|
||||
if (!node || !node->mempool) {
|
||||
RESTERR(req, HTTP_NOT_FOUND, "Mempool disabled or instance not found");
|
||||
return nullptr;
|
||||
}
|
||||
return g_rpc_node->mempool;
|
||||
return node->mempool;
|
||||
}
|
||||
|
||||
static RetFormat ParseDataFormat(std::string& param, const std::string& strReq)
|
||||
@@ -129,7 +131,8 @@ static bool CheckWarmup(HTTPRequest* req)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rest_headers(HTTPRequest* req,
|
||||
static bool rest_headers(const util::Ref& context,
|
||||
HTTPRequest* req,
|
||||
const std::string& strURIPart)
|
||||
{
|
||||
if (!CheckWarmup(req))
|
||||
@@ -270,12 +273,12 @@ static bool rest_block(HTTPRequest* req,
|
||||
}
|
||||
}
|
||||
|
||||
static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_block_extended(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
return rest_block(req, strURIPart, true);
|
||||
}
|
||||
|
||||
static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_block_notxdetails(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
return rest_block(req, strURIPart, false);
|
||||
}
|
||||
@@ -283,7 +286,7 @@ static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPa
|
||||
// A bit of a hack - dependency on a function defined in rpc/blockchain.cpp
|
||||
UniValue getblockchaininfo(const JSONRPCRequest& request);
|
||||
|
||||
static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_chaininfo(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
if (!CheckWarmup(req))
|
||||
return false;
|
||||
@@ -292,7 +295,7 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
|
||||
|
||||
switch (rf) {
|
||||
case RetFormat::JSON: {
|
||||
JSONRPCRequest jsonRequest;
|
||||
JSONRPCRequest jsonRequest(context);
|
||||
jsonRequest.params = UniValue(UniValue::VARR);
|
||||
UniValue chainInfoObject = getblockchaininfo(jsonRequest);
|
||||
std::string strJSON = chainInfoObject.write() + "\n";
|
||||
@@ -306,11 +309,11 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
|
||||
}
|
||||
}
|
||||
|
||||
static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_mempool_info(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
if (!CheckWarmup(req))
|
||||
return false;
|
||||
const CTxMemPool* mempool = GetMemPool(req);
|
||||
const CTxMemPool* mempool = GetMemPool(context, req);
|
||||
if (!mempool) return false;
|
||||
std::string param;
|
||||
const RetFormat rf = ParseDataFormat(param, strURIPart);
|
||||
@@ -330,10 +333,10 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
|
||||
}
|
||||
}
|
||||
|
||||
static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_mempool_contents(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
if (!CheckWarmup(req)) return false;
|
||||
const CTxMemPool* mempool = GetMemPool(req);
|
||||
const CTxMemPool* mempool = GetMemPool(context, req);
|
||||
if (!mempool) return false;
|
||||
std::string param;
|
||||
const RetFormat rf = ParseDataFormat(param, strURIPart);
|
||||
@@ -353,7 +356,7 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar
|
||||
}
|
||||
}
|
||||
|
||||
static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_tx(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
if (!CheckWarmup(req))
|
||||
return false;
|
||||
@@ -409,7 +412,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
|
||||
}
|
||||
}
|
||||
|
||||
static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
|
||||
static bool rest_getutxos(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
|
||||
{
|
||||
if (!CheckWarmup(req))
|
||||
return false;
|
||||
@@ -518,7 +521,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
|
||||
};
|
||||
|
||||
if (fCheckMemPool) {
|
||||
const CTxMemPool* mempool = GetMemPool(req);
|
||||
const CTxMemPool* mempool = GetMemPool(context, req);
|
||||
if (!mempool) return false;
|
||||
// use db+mempool as cache backend in case user likes to query mempool
|
||||
LOCK2(cs_main, mempool->cs);
|
||||
@@ -595,7 +598,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
|
||||
}
|
||||
}
|
||||
|
||||
static bool rest_blockhash_by_height(HTTPRequest* req,
|
||||
static bool rest_blockhash_by_height(const util::Ref& context, HTTPRequest* req,
|
||||
const std::string& str_uri_part)
|
||||
{
|
||||
if (!CheckWarmup(req)) return false;
|
||||
@@ -643,7 +646,7 @@ static bool rest_blockhash_by_height(HTTPRequest* req,
|
||||
|
||||
static const struct {
|
||||
const char* prefix;
|
||||
bool (*handler)(HTTPRequest* req, const std::string& strReq);
|
||||
bool (*handler)(const util::Ref& context, HTTPRequest* req, const std::string& strReq);
|
||||
} uri_prefixes[] = {
|
||||
{"/rest/tx/", rest_tx},
|
||||
{"/rest/block/notxdetails/", rest_block_notxdetails},
|
||||
@@ -656,10 +659,12 @@ static const struct {
|
||||
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
|
||||
};
|
||||
|
||||
void StartREST()
|
||||
void StartREST(const util::Ref& context)
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
|
||||
RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler);
|
||||
for (const auto& up : uri_prefixes) {
|
||||
auto handler = [&context, up](HTTPRequest* req, const std::string& prefix) { return up.handler(context, req, prefix); };
|
||||
RegisterHTTPHandler(up.prefix, false, handler);
|
||||
}
|
||||
}
|
||||
|
||||
void InterruptREST()
|
||||
|
||||
Reference in New Issue
Block a user