diff options
-rw-r--r-- | build_msvc/bitcoind/bitcoind.vcxproj | 3 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/bitcoind.cpp | 15 | ||||
-rw-r--r-- | src/init/bitcoin-node.cpp | 43 | ||||
-rw-r--r-- | src/init/bitcoind.cpp | 29 | ||||
-rw-r--r-- | src/interfaces/init.h | 14 | ||||
-rw-r--r-- | src/node/context.h | 3 |
7 files changed, 105 insertions, 6 deletions
diff --git a/build_msvc/bitcoind/bitcoind.vcxproj b/build_msvc/bitcoind/bitcoind.vcxproj index 48dfafaee0..c2c32af838 100644 --- a/build_msvc/bitcoind/bitcoind.vcxproj +++ b/build_msvc/bitcoind/bitcoind.vcxproj @@ -10,6 +10,9 @@ </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\bitcoind.cpp" /> + <ClCompile Include="..\..\src\init\bitcoind.cpp"> + <ObjectFileName>$(IntDir)init_bitcoind.obj</ObjectFileName> + </ClCompile> </ItemGroup> <ItemGroup> <ProjectReference Include="..\libbitcoinconsensus\libbitcoinconsensus.vcxproj"> diff --git a/src/Makefile.am b/src/Makefile.am index 8d17338938..71dd7b65a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -640,13 +640,13 @@ bitcoin_bin_ldadd = \ bitcoin_bin_ldadd += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(SQLITE_LIBS) -bitcoind_SOURCES = $(bitcoin_daemon_sources) +bitcoind_SOURCES = $(bitcoin_daemon_sources) init/bitcoind.cpp bitcoind_CPPFLAGS = $(bitcoin_bin_cppflags) bitcoind_CXXFLAGS = $(bitcoin_bin_cxxflags) bitcoind_LDFLAGS = $(bitcoin_bin_ldflags) bitcoind_LDADD = $(LIBBITCOIN_SERVER) $(bitcoin_bin_ldadd) -bitcoin_node_SOURCES = $(bitcoin_daemon_sources) +bitcoin_node_SOURCES = $(bitcoin_daemon_sources) init/bitcoin-node.cpp bitcoin_node_CPPFLAGS = $(bitcoin_bin_cppflags) bitcoin_node_CXXFLAGS = $(bitcoin_bin_cxxflags) bitcoin_node_LDFLAGS = $(bitcoin_bin_ldflags) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 225b8b1ec4..cf9e4fad44 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -12,6 +12,7 @@ #include <compat.h> #include <init.h> #include <interfaces/chain.h> +#include <interfaces/init.h> #include <node/context.h> #include <node/ui_interface.h> #include <noui.h> @@ -104,10 +105,8 @@ int fork_daemon(bool nochdir, bool noclose, TokenPipeEnd& endpoint) #endif -static bool AppInit(int argc, char* argv[]) +static bool AppInit(NodeContext& node, int argc, char* argv[]) { - NodeContext node; - bool fRet = false; util::ThreadSetInternalName("init"); @@ -254,10 +253,18 @@ int main(int argc, char* argv[]) util::WinCmdLineArgs winArgs; std::tie(argc, argv) = winArgs.get(); #endif + + NodeContext node; + int exit_status; + std::unique_ptr<interfaces::Init> init = interfaces::MakeNodeInit(node, argc, argv, exit_status); + if (!init) { + return exit_status; + } + SetupEnvironment(); // Connect bitcoind signal handlers noui_connect(); - return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); + return (AppInit(node, argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/init/bitcoin-node.cpp b/src/init/bitcoin-node.cpp new file mode 100644 index 0000000000..b1c8a5b561 --- /dev/null +++ b/src/init/bitcoin-node.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <interfaces/init.h> +#include <interfaces/ipc.h> +#include <node/context.h> + +#include <memory> + +namespace init { +namespace { +const char* EXE_NAME = "bitcoin-node"; + +class BitcoinNodeInit : public interfaces::Init +{ +public: + BitcoinNodeInit(NodeContext& node, const char* arg0) + : m_node(node), + m_ipc(interfaces::MakeIpc(EXE_NAME, arg0, *this)) + { + m_node.init = this; + } + interfaces::Ipc* ipc() override { return m_ipc.get(); } + NodeContext& m_node; + std::unique_ptr<interfaces::Ipc> m_ipc; +}; +} // namespace +} // namespace init + +namespace interfaces { +std::unique_ptr<Init> MakeNodeInit(NodeContext& node, int argc, char* argv[], int& exit_status) +{ + auto init = std::make_unique<init::BitcoinNodeInit>(node, argc > 0 ? argv[0] : ""); + // Check if bitcoin-node is being invoked as an IPC server. If so, then + // bypass normal execution and just respond to requests over the IPC + // channel and return null. + if (init->m_ipc->startSpawnedProcess(argc, argv, exit_status)) { + return nullptr; + } + return init; +} +} // namespace interfaces diff --git a/src/init/bitcoind.cpp b/src/init/bitcoind.cpp new file mode 100644 index 0000000000..1e17ce4d3c --- /dev/null +++ b/src/init/bitcoind.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <interfaces/init.h> +#include <node/context.h> + +#include <memory> + +namespace init { +namespace { +class BitcoindInit : public interfaces::Init +{ +public: + BitcoindInit(NodeContext& node) : m_node(node) + { + m_node.init = this; + } + NodeContext& m_node; +}; +} // namespace +} // namespace init + +namespace interfaces { +std::unique_ptr<Init> MakeNodeInit(NodeContext& node, int argc, char* argv[], int& exit_status) +{ + return std::make_unique<init::BitcoindInit>(node); +} +} // namespace interfaces diff --git a/src/interfaces/init.h b/src/interfaces/init.h index 8ffd017656..8aea027f01 100644 --- a/src/interfaces/init.h +++ b/src/interfaces/init.h @@ -31,6 +31,20 @@ public: virtual std::unique_ptr<WalletClient> makeWalletClient(Chain& chain); virtual Ipc* ipc(); }; + +//! Return implementation of Init interface for the node process. If the argv +//! indicates that this is a child process spawned to handle requests from a +//! parent process, this blocks and handles requests, then returns null and a +//! status code to exit with. If this returns non-null, the caller can start up +//! normally and use the Init object to spawn and connect to other processes +//! while it is running. +std::unique_ptr<Init> MakeNodeInit(NodeContext& node, int argc, char* argv[], int& exit_status); + +//! Return implementation of Init interface for the wallet process. +std::unique_ptr<Init> MakeWalletInit(int argc, char* argv[], int& exit_status); + +//! Return implementation of Init interface for the gui process. +std::unique_ptr<Init> MakeGuiInit(int argc, char* argv[]); } // namespace interfaces #endif // BITCOIN_INTERFACES_INIT_H diff --git a/src/node/context.h b/src/node/context.h index 2be9a584e6..06adb33a80 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -22,6 +22,7 @@ class PeerManager; namespace interfaces { class Chain; class ChainClient; +class Init; class WalletClient; } // namespace interfaces @@ -36,6 +37,8 @@ class WalletClient; //! any member functions. It should just be a collection of references that can //! be used without pulling in unwanted dependencies or functionality. struct NodeContext { + //! Init interface for initializing current process and connecting to other processes. + interfaces::Init* init{nullptr}; std::unique_ptr<CAddrMan> addrman; std::unique_ptr<CConnman> connman; std::unique_ptr<CTxMemPool> mempool; |