diff --git a/src/interfaces/node.h b/src/interfaces/node.h --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -284,12 +284,14 @@ virtual std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0; - //! Return pointer to internal chain interface, useful for testing. + //! Get and set internal node context. Useful for testing, but not + //! accessible across processes. virtual NodeContext *context() { return nullptr; } + virtual void setContext(NodeContext *context) {} }; //! Return implementation of Node interface. -std::unique_ptr MakeNode(); +std::unique_ptr MakeNode(NodeContext *context = nullptr); } // namespace interfaces diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -65,6 +65,7 @@ class NodeImpl : public Node { public: + NodeImpl(NodeContext *context) { setContext(context); } void initError(const std::string &message) override { InitError(Untranslated(message)); } @@ -108,13 +109,13 @@ bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor) override { - m_context.chain = MakeChain(m_context, config.GetChainParams()); + m_context->chain = MakeChain(*m_context, config.GetChainParams()); return AppInitMain(config, rpcServer, httpRPCRequestProcessor, - m_context); + *m_context); } void appShutdown() override { - Interrupt(m_context); - Shutdown(m_context); + Interrupt(*m_context); + Shutdown(*m_context); } void startShutdown() override { StartShutdown(); } bool shutdownRequested() override { return ShutdownRequested(); } @@ -126,20 +127,22 @@ StopMapPort(); } } + // PR18571: return SetupServerArgs(*m_context) + // See https://reviews.bitcoinabc.org/D7993 void setupServerArgs() override { return SetupServerArgs(); } bool getProxy(Network net, proxyType &proxy_info) override { return GetProxy(net, proxy_info); } size_t getNodeCount(CConnman::NumConnections flags) override { - return m_context.connman ? m_context.connman->GetNodeCount(flags) - : 0; + return m_context->connman ? m_context->connman->GetNodeCount(flags) + : 0; } bool getNodesStats(NodesStats &stats) override { stats.clear(); - if (m_context.connman) { + if (m_context->connman) { std::vector stats_temp; - m_context.connman->GetNodeStats(stats_temp); + m_context->connman->GetNodeStats(stats_temp); stats.reserve(stats_temp.size()); for (auto &node_stats_temp : stats_temp) { @@ -161,52 +164,52 @@ return false; } bool getBanned(banmap_t &banmap) override { - if (m_context.banman) { - m_context.banman->GetBanned(banmap); + if (m_context->banman) { + m_context->banman->GetBanned(banmap); return true; } return false; } bool ban(const CNetAddr &net_addr, int64_t ban_time_offset) override { - if (m_context.banman) { - m_context.banman->Ban(net_addr, ban_time_offset); + if (m_context->banman) { + m_context->banman->Ban(net_addr, ban_time_offset); return true; } return false; } bool unban(const CSubNet &ip) override { - if (m_context.banman) { - m_context.banman->Unban(ip); + if (m_context->banman) { + m_context->banman->Unban(ip); return true; } return false; } bool disconnect(const CNetAddr &net_addr) override { - if (m_context.connman) { - return m_context.connman->DisconnectNode(net_addr); + if (m_context->connman) { + return m_context->connman->DisconnectNode(net_addr); } return false; } bool disconnect(NodeId id) override { - if (m_context.connman) { - return m_context.connman->DisconnectNode(id); + if (m_context->connman) { + return m_context->connman->DisconnectNode(id); } return false; } int64_t getTotalBytesRecv() override { - return m_context.connman ? m_context.connman->GetTotalBytesRecv() - : 0; + return m_context->connman ? m_context->connman->GetTotalBytesRecv() + : 0; } int64_t getTotalBytesSent() override { - return m_context.connman ? m_context.connman->GetTotalBytesSent() - : 0; + return m_context->connman ? m_context->connman->GetTotalBytesSent() + : 0; } size_t getMempoolSize() override { - return m_context.mempool ? m_context.mempool->size() : 0; + return m_context->mempool ? m_context->mempool->size() : 0; } size_t getMempoolDynamicUsage() override { - return m_context.mempool ? m_context.mempool->DynamicMemoryUsage() - : 0; + return m_context->mempool ? m_context->mempool->DynamicMemoryUsage() + : 0; } bool getHeaderTip(int &height, int64_t &block_time) override { LOCK(::cs_main); @@ -243,16 +246,16 @@ bool getReindex() override { return ::fReindex; } bool getImporting() override { return ::fImporting; } void setNetworkActive(bool active) override { - if (m_context.connman) { - m_context.connman->SetNetworkActive(active); + if (m_context->connman) { + m_context->connman->SetNetworkActive(active); } } bool getNetworkActive() override { - return m_context.connman && m_context.connman->GetNetworkActive(); + return m_context->connman && m_context->connman->GetNetworkActive(); } CFeeRate estimateSmartFee() override { - return m_context.mempool ? m_context.mempool->estimateFee() - : CFeeRate(); + return m_context->mempool ? m_context->mempool->estimateFee() + : CFeeRate(); } CFeeRate getDustRelayFee() override { return ::dustRelayFee; } UniValue executeRpc(Config &config, const std::string &command, @@ -287,7 +290,7 @@ } std::vector> getWallets() override { std::vector> wallets; - for (auto &client : m_context.chain_clients) { + for (auto &client : m_context->chain_clients) { auto client_wallets = client->getWallets(); std::move(client_wallets.begin(), client_wallets.end(), std::back_inserter(wallets)); @@ -299,7 +302,7 @@ bilingual_str &error, std::vector &warnings) const override { return MakeWallet( - LoadWallet(params, *m_context.chain, name, error, warnings)); + LoadWallet(params, *m_context->chain, name, error, warnings)); } WalletCreationStatus createWallet(const CChainParams ¶ms, const SecureString &passphrase, @@ -308,7 +311,7 @@ std::unique_ptr &result) override { std::shared_ptr wallet; WalletCreationStatus status = CreateWallet( - params, *m_context.chain, passphrase, wallet_creation_flags, + params, *m_context->chain, passphrase, wallet_creation_flags, name, error, warnings, wallet); result = MakeWallet(wallet); return status; @@ -363,14 +366,22 @@ GuessVerificationProgress(Params().TxData(), block)); })); } - NodeContext *context() override { return &m_context; } - NodeContext m_context; + NodeContext *context() override { return m_context; } + void setContext(NodeContext *context) override { + m_context = context; + if (context) { + m_context_ref.Set(*context); + } else { + m_context_ref.Clear(); + } + } + NodeContext *m_context{nullptr}; util::Ref m_context_ref{m_context}; }; } // namespace -std::unique_ptr MakeNode() { - return std::make_unique(); +std::unique_ptr MakeNode(NodeContext *context) { + return std::make_unique(context); } } // namespace interfaces diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -510,7 +511,9 @@ SetupEnvironment(); util::ThreadSetInternalName("main"); - std::unique_ptr node = interfaces::MakeNode(); + NodeContext node_context; + std::unique_ptr node = + interfaces::MakeNode(&node_context); // Subscribe to global signals from core std::unique_ptr handler_message_box = diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,7 @@ */ void TestAddAddressesToSendBook(interfaces::Node &node) { TestChain100Setup test; + node.setContext(&test.m_node); std::shared_ptr wallet = std::make_shared( Params(), node.context()->chain.get(), WalletLocation(), diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -55,7 +55,9 @@ // All tests must use their own testing setup (if needed). { BasicTestingSetup dummy{CBaseChainParams::REGTEST}; } - std::unique_ptr node = interfaces::MakeNode(); + NodeContext node_context; + std::unique_ptr node = + interfaces::MakeNode(&node_context); bool fInvalid = false; diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -112,8 +112,7 @@ test.CreateAndProcessBlock( {}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey())); } - node.context()->connman = std::move(test.m_node.connman); - node.context()->mempool = std::move(test.m_node.mempool); + node.setContext(&test.m_node); std::shared_ptr wallet = std::make_shared( Params(), node.context()->chain.get(), WalletLocation(), WalletDatabase::CreateMock()); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include #include @@ -100,6 +102,9 @@ InitSignatureCache(); InitScriptExecutionCache(); + m_node.chain = interfaces::MakeChain(m_node, Params()); + g_wallet_init_interface.Construct(m_node); + fCheckBlockIndex = true; static bool noui_connected = false; if (!noui_connected) {