From 95cccf8a4b392959c1fd7ec0647e04eb13880865 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 5 Mar 2021 14:33:41 +0100 Subject: util: introduce helper AnyPtr to access std::any instances Co-authored-by: Russell Yanofsky --- src/util/system.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/util/system.h b/src/util/system.h index 291f3f5541..29657e56e2 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -500,6 +501,18 @@ inline void insert(std::set& dst, const Tsrc& src) { dst.insert(src.begin(), src.end()); } +/** + * Helper function to access the contained object of a std::any instance. + * Returns a pointer to the object if passed instance has a value and the type + * matches, nullptr otherwise. + */ +template +T* AnyPtr(const std::any& any) noexcept +{ + T* const* ptr = std::any_cast(&any); + return ptr ? *ptr : nullptr; +} + #ifdef WIN32 class WinCmdLineArgs { -- cgit v1.2.3 From 8dbb87a3932f81e23ba7afd865b9aeeb535f0c20 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Tue, 1 Dec 2020 00:36:36 +0100 Subject: refactor: replace util::Ref by std::any (C++17) --- src/bitcoind.cpp | 5 +++-- src/httprpc.cpp | 4 ++-- src/httprpc.h | 8 +++----- src/init.cpp | 4 ++-- src/init.h | 6 ++---- src/node/interfaces.cpp | 8 ++++---- src/rest.cpp | 42 +++++++++++++++++++++------------------- src/rpc/blockchain.cpp | 14 +++++++------- src/rpc/blockchain.h | 12 +++++------- src/rpc/misc.cpp | 14 +++++++------- src/rpc/request.h | 11 ++++------- src/rpc/server.cpp | 4 ++-- src/test/rpc_tests.cpp | 5 +++-- src/wallet/interfaces.cpp | 3 +-- src/wallet/rpcwallet.cpp | 8 ++++---- src/wallet/rpcwallet.h | 3 ++- src/wallet/test/wallet_tests.cpp | 8 ++++---- 17 files changed, 77 insertions(+), 82 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 1b4ca3e9a8..80ab69c131 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -142,7 +143,7 @@ static bool AppInit(int argc, char* argv[]) // end, which is interpreted as failure to start. TokenPipeEnd daemon_ep; #endif - util::Ref context{node}; + std::any context{&node}; try { if (!CheckDataDirOption()) { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 867ddb090e..16ab38e0b2 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -144,7 +144,7 @@ static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUserna return multiUserAuthorized(strUserPass); } -static bool HTTPReq_JSONRPC(const util::Ref& context, HTTPRequest* req) +static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req) { // JSONRPC handles only POST if (req->GetRequestMethod() != HTTPRequest::POST) { @@ -288,7 +288,7 @@ static bool InitRPCAuthentication() return true; } -bool StartHTTPRPC(const util::Ref& context) +bool StartHTTPRPC(const std::any& context) { LogPrint(BCLog::RPC, "Starting HTTP RPC server\n"); if (!InitRPCAuthentication()) diff --git a/src/httprpc.h b/src/httprpc.h index 97af6f7bb1..5a3b990646 100644 --- a/src/httprpc.h +++ b/src/httprpc.h @@ -5,14 +5,12 @@ #ifndef BITCOIN_HTTPRPC_H #define BITCOIN_HTTPRPC_H -namespace util { -class Ref; -} // namespace util +#include /** Start HTTP RPC subsystem. * Precondition; HTTP and RPC has been started. */ -bool StartHTTPRPC(const util::Ref& context); +bool StartHTTPRPC(const std::any& context); /** Interrupt HTTP RPC subsystem. */ void InterruptHTTPRPC(); @@ -24,7 +22,7 @@ void StopHTTPRPC(); /** Start HTTP REST subsystem. * Precondition; HTTP and RPC has been started. */ -void StartREST(const util::Ref& context); +void StartREST(const std::any& context); /** Interrupt RPC REST subsystem. */ void InterruptREST(); diff --git a/src/init.cpp b/src/init.cpp index f4b7699233..9fb3f1294c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -787,7 +787,7 @@ static bool InitSanityCheck() return true; } -static bool AppInitServers(const util::Ref& context, NodeContext& node) +static bool AppInitServers(const std::any& context, NodeContext& node) { const ArgsManager& args = *Assert(node.args); RPCServer::OnStarted(&OnRPCStarted); @@ -1276,7 +1276,7 @@ bool AppInitInterfaces(NodeContext& node) return true; } -bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) +bool AppInitMain(const std::any& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) { const ArgsManager& args = *Assert(node.args); const CChainParams& chainparams = Params(); diff --git a/src/init.h b/src/init.h index 34bca09dd1..5d01d4c1ac 100644 --- a/src/init.h +++ b/src/init.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_INIT_H #define BITCOIN_INIT_H +#include #include #include @@ -22,9 +23,6 @@ struct BlockAndHeaderTipInfo; namespace boost { class thread_group; } // namespace boost -namespace util { -class Ref; -} // namespace util /** Interrupt threads */ void Interrupt(NodeContext& node); @@ -66,7 +64,7 @@ bool AppInitInterfaces(NodeContext& node); * @note This should only be done after daemonization. Call Shutdown() if this function fails. * @pre Parameters should be parsed and config file should be read, AppInitLockDataDirectory should have been called. */ -bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info = nullptr); +bool AppInitMain(const std::any& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info = nullptr); /** * Register all arguments with the ArgsManager diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 50c8c29175..0f4094e14b 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -49,6 +48,7 @@ #include #endif +#include #include #include #include @@ -298,13 +298,13 @@ public: { m_context = context; if (context) { - m_context_ref.Set(*context); + m_context_ref = context; } else { - m_context_ref.Clear(); + m_context_ref.reset(); } } NodeContext* m_context{nullptr}; - util::Ref m_context_ref; + std::any m_context_ref; }; bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock& lock, const CChain& active) diff --git a/src/rest.cpp b/src/rest.cpp index 71426a4dc4..aa97470ca7 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -18,10 +18,12 @@ #include #include #include -#include +#include #include #include +#include + #include #include @@ -73,10 +75,10 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me * context is not found. * @returns Pointer to the node context or nullptr if not found. */ -static NodeContext* GetNodeContext(const util::Ref& context, HTTPRequest* req) +static NodeContext* GetNodeContext(const std::any& context, HTTPRequest* req) { - NodeContext* node = context.Has() ? &context.Get() : nullptr; - if (!node) { + auto node_context = util::AnyPtr(context); + if (!node_context) { RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("%s:%d (%s)\n" "Internal bug detected: Node context not found!\n" @@ -84,7 +86,7 @@ static NodeContext* GetNodeContext(const util::Ref& context, HTTPRequest* req) __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT)); return nullptr; } - return node; + return node_context; } /** @@ -94,14 +96,14 @@ static NodeContext* GetNodeContext(const util::Ref& context, HTTPRequest* req) * context mempool is not found. * @returns Pointer to the mempool or nullptr if no mempool found. */ -static CTxMemPool* GetMemPool(const util::Ref& context, HTTPRequest* req) +static CTxMemPool* GetMemPool(const std::any& context, HTTPRequest* req) { - NodeContext* node = context.Has() ? &context.Get() : nullptr; - if (!node || !node->mempool) { + auto node_context = util::AnyPtr(context); + if (!node_context || !node_context->mempool) { RESTERR(req, HTTP_NOT_FOUND, "Mempool disabled or instance not found"); return nullptr; } - return node->mempool.get(); + return node_context->mempool.get(); } static RetFormat ParseDataFormat(std::string& param, const std::string& strReq) @@ -151,7 +153,7 @@ static bool CheckWarmup(HTTPRequest* req) return true; } -static bool rest_headers(const util::Ref& context, +static bool rest_headers(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { @@ -293,12 +295,12 @@ static bool rest_block(HTTPRequest* req, } } -static bool rest_block_extended(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_block_extended(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { return rest_block(req, strURIPart, true); } -static bool rest_block_notxdetails(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_block_notxdetails(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { return rest_block(req, strURIPart, false); } @@ -306,7 +308,7 @@ static bool rest_block_notxdetails(const util::Ref& context, HTTPRequest* req, c // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp RPCHelpMan getblockchaininfo(); -static bool rest_chaininfo(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; @@ -329,7 +331,7 @@ static bool rest_chaininfo(const util::Ref& context, HTTPRequest* req, const std } } -static bool rest_mempool_info(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_mempool_info(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; @@ -353,7 +355,7 @@ static bool rest_mempool_info(const util::Ref& context, HTTPRequest* req, const } } -static bool rest_mempool_contents(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_mempool_contents(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; const CTxMemPool* mempool = GetMemPool(context, req); @@ -376,7 +378,7 @@ static bool rest_mempool_contents(const util::Ref& context, HTTPRequest* req, co } } -static bool rest_tx(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; @@ -435,7 +437,7 @@ static bool rest_tx(const util::Ref& context, HTTPRequest* req, const std::strin } } -static bool rest_getutxos(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) +static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; @@ -621,7 +623,7 @@ static bool rest_getutxos(const util::Ref& context, HTTPRequest* req, const std: } } -static bool rest_blockhash_by_height(const util::Ref& context, HTTPRequest* req, +static bool rest_blockhash_by_height(const std::any& context, HTTPRequest* req, const std::string& str_uri_part) { if (!CheckWarmup(req)) return false; @@ -669,7 +671,7 @@ static bool rest_blockhash_by_height(const util::Ref& context, HTTPRequest* req, static const struct { const char* prefix; - bool (*handler)(const util::Ref& context, HTTPRequest* req, const std::string& strReq); + bool (*handler)(const std::any& context, HTTPRequest* req, const std::string& strReq); } uri_prefixes[] = { {"/rest/tx/", rest_tx}, {"/rest/block/notxdetails/", rest_block_notxdetails}, @@ -682,7 +684,7 @@ static const struct { {"/rest/blockhashbyheight/", rest_blockhash_by_height}, }; -void StartREST(const util::Ref& context) +void StartREST(const std::any& context) { for (const auto& up : uri_prefixes) { auto handler = [&context, up](HTTPRequest* req, const std::string& prefix) { return up.handler(context, req, prefix); }; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f0ad141fa9..961478155f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -56,15 +55,16 @@ static Mutex cs_blockchange; static std::condition_variable cond_blockchange; static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange); -NodeContext& EnsureNodeContext(const util::Ref& context) +NodeContext& EnsureNodeContext(const std::any& context) { - if (!context.Has()) { + auto node_context = util::AnyPtr(context); + if (!node_context) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Node context not found"); } - return context.Get(); + return *node_context; } -CTxMemPool& EnsureMemPool(const util::Ref& context) +CTxMemPool& EnsureMemPool(const std::any& context) { const NodeContext& node = EnsureNodeContext(context); if (!node.mempool) { @@ -73,7 +73,7 @@ CTxMemPool& EnsureMemPool(const util::Ref& context) return *node.mempool; } -ChainstateManager& EnsureChainman(const util::Ref& context) +ChainstateManager& EnsureChainman(const std::any& context) { const NodeContext& node = EnsureNodeContext(context); if (!node.chainman) { @@ -82,7 +82,7 @@ ChainstateManager& EnsureChainman(const util::Ref& context) return *node.chainman; } -CBlockPolicyEstimator& EnsureFeeEstimator(const util::Ref& context) +CBlockPolicyEstimator& EnsureFeeEstimator(const std::any& context) { NodeContext& node = EnsureNodeContext(context); if (!node.fee_estimator) { diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index e719dfc702..cd04c9a10f 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -23,9 +24,6 @@ class CTxMemPool; class ChainstateManager; class UniValue; struct NodeContext; -namespace util { -class Ref; -} // namespace util static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5; @@ -58,10 +56,10 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr); -NodeContext& EnsureNodeContext(const util::Ref& context); -CTxMemPool& EnsureMemPool(const util::Ref& context); -ChainstateManager& EnsureChainman(const util::Ref& context); -CBlockPolicyEstimator& EnsureFeeEstimator(const util::Ref& context); +NodeContext& EnsureNodeContext(const std::any& context); +CTxMemPool& EnsureMemPool(const std::any& context); +ChainstateManager& EnsureChainman(const std::any& context); +CBlockPolicyEstimator& EnsureFeeEstimator(const std::any& context); /** * Helper to create UTXO snapshots given a chainstate and a file handle. diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 143be1274e..1df5c51718 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -17,7 +17,6 @@ #include