mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
multiprocess: Add -ipcbind option to bitcoin-node
Add `-ipcbind` option to `bitcoin-node` to listen on an IPC socket and accept connections from other processes. In the future, there will be an `-ipcconnect` option added to `bitcoin-wallet` and `bitcoin-node` to allow wallet and gui processes to connect to the node and access it. Example usage: src/bitcoin-node -regtest -debug -ipcbind=unix src/bitcoin-wallet -regtest -ipcconnect=unix info src/bitcoin-gui -regtest -ipcconnect=unix src/bitcoin-mine -regtest -ipcconnect=unix
This commit is contained in:
parent
73fe7d7230
commit
30073e6b3a
10 changed files with 34 additions and 7 deletions
|
@ -109,10 +109,11 @@ int fork_daemon(bool nochdir, bool noclose, TokenPipeEnd& endpoint)
|
|||
|
||||
#endif
|
||||
|
||||
static bool ParseArgs(ArgsManager& args, int argc, char* argv[])
|
||||
static bool ParseArgs(NodeContext& node, int argc, char* argv[])
|
||||
{
|
||||
ArgsManager& args{*Assert(node.args)};
|
||||
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
|
||||
SetupServerArgs(args);
|
||||
SetupServerArgs(args, node.init->canListenIpc());
|
||||
std::string error;
|
||||
if (!args.ParseParameters(argc, argv, error)) {
|
||||
return InitError(Untranslated(strprintf("Error parsing command line arguments: %s", error)));
|
||||
|
@ -268,7 +269,7 @@ MAIN_FUNCTION
|
|||
|
||||
// Interpret command line arguments
|
||||
ArgsManager& args = *Assert(node.args);
|
||||
if (!ParseArgs(args, argc, argv)) return EXIT_FAILURE;
|
||||
if (!ParseArgs(node, argc, argv)) return EXIT_FAILURE;
|
||||
// Process early info return commands such as -help or -version
|
||||
if (ProcessInitCommands(args)) return EXIT_SUCCESS;
|
||||
|
||||
|
|
|
@ -635,6 +635,9 @@ std::string ArgsManager::GetHelpMessage() const
|
|||
case OptionsCategory::RPC:
|
||||
usage += HelpMessageGroup("RPC server options:");
|
||||
break;
|
||||
case OptionsCategory::IPC:
|
||||
usage += HelpMessageGroup("IPC interprocess connection options:");
|
||||
break;
|
||||
case OptionsCategory::WALLET:
|
||||
usage += HelpMessageGroup("Wallet options:");
|
||||
break;
|
||||
|
|
|
@ -64,6 +64,7 @@ enum class OptionsCategory {
|
|||
COMMANDS,
|
||||
REGISTER_COMMANDS,
|
||||
CLI_COMMANDS,
|
||||
IPC,
|
||||
|
||||
HIDDEN // Always the last option to avoid printing these in the help
|
||||
};
|
||||
|
|
17
src/init.cpp
17
src/init.cpp
|
@ -29,6 +29,7 @@
|
|||
#include <init/common.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <interfaces/init.h>
|
||||
#include <interfaces/ipc.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <interfaces/node.h>
|
||||
#include <kernel/context.h>
|
||||
|
@ -441,7 +442,7 @@ static void OnRPCStopped()
|
|||
LogDebug(BCLog::RPC, "RPC stopped.\n");
|
||||
}
|
||||
|
||||
void SetupServerArgs(ArgsManager& argsman)
|
||||
void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
||||
{
|
||||
SetupHelpOptions(argsman);
|
||||
argsman.AddArg("-help-debug", "Print help message with debugging options and exit", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); // server-only for now
|
||||
|
@ -676,6 +677,9 @@ void SetupServerArgs(ArgsManager& argsman)
|
|||
argsman.AddArg("-rpcwhitelistdefault", "Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc server acts as if all rpc users are subject to empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault is set to 1 and no -rpcwhitelist is set, rpc server acts as if all rpc users are subject to empty whitelists.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-server", "Accept command line and JSON-RPC commands", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||
if (can_listen_ipc) {
|
||||
argsman.AddArg("-ipcbind=<address>", "Bind to Unix socket address and listen for incoming connections. Valid address values are \"unix\" to listen on the default path, <datadir>/node.sock, or \"unix:/custom/path\" to specify a custom path. Can be specified multiple times to listen on multiple paths. Default behavior is not to listen on any path. If relative paths are specified, they are interpreted relative to the network data directory. If paths include any parent directory components and the parent directories do not exist, they will be created.", ArgsManager::ALLOW_ANY, OptionsCategory::IPC);
|
||||
}
|
||||
|
||||
#if HAVE_DECL_FORK
|
||||
argsman.AddArg("-daemon", strprintf("Run in the background as a daemon and accept commands (default: %d)", DEFAULT_DAEMON), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
|
@ -1200,6 +1204,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
g_wallet_init_interface.Construct(node);
|
||||
uiInterface.InitWallet();
|
||||
|
||||
if (interfaces::Ipc* ipc = node.init->ipc()) {
|
||||
for (std::string address : gArgs.GetArgs("-ipcbind")) {
|
||||
try {
|
||||
ipc->listenAddress(address);
|
||||
} catch (const std::exception& e) {
|
||||
return InitError(strprintf(Untranslated("Unable to bind to IPC address '%s'. %s"), address, e.what()));
|
||||
}
|
||||
LogPrintf("Listening for IPC requests on address %s\n", address);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register RPC commands regardless of -server setting so they will be
|
||||
* available in the GUI RPC console even if external calls are disabled.
|
||||
*/
|
||||
|
|
|
@ -74,7 +74,7 @@ bool AppInitMain(node::NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip
|
|||
/**
|
||||
* Register all arguments with the ArgsManager
|
||||
*/
|
||||
void SetupServerArgs(ArgsManager& argsman);
|
||||
void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc=false);
|
||||
|
||||
/** Validates requirements to run the indexes and spawns each index initial sync thread */
|
||||
bool StartIndexBackgroundSync(node::NodeContext& node);
|
||||
|
|
|
@ -34,6 +34,11 @@ public:
|
|||
}
|
||||
std::unique_ptr<interfaces::Echo> makeEcho() override { return interfaces::MakeEcho(); }
|
||||
interfaces::Ipc* ipc() override { return m_ipc.get(); }
|
||||
// bitcoin-gui accepts -ipcbind option even though it does not use it
|
||||
// directly. It just returns true here to accept the option because
|
||||
// bitcoin-node accepts the option, and bitcoin-gui accepts all bitcoin-node
|
||||
// options and will start the node with those options.
|
||||
bool canListenIpc() override { return true; }
|
||||
node::NodeContext m_node;
|
||||
std::unique_ptr<interfaces::Ipc> m_ipc;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
}
|
||||
std::unique_ptr<interfaces::Echo> makeEcho() override { return interfaces::MakeEcho(); }
|
||||
interfaces::Ipc* ipc() override { return m_ipc.get(); }
|
||||
bool canListenIpc() override { return true; }
|
||||
node::NodeContext& m_node;
|
||||
std::unique_ptr<interfaces::Ipc> m_ipc;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
virtual std::unique_ptr<WalletLoader> makeWalletLoader(Chain& chain) { return nullptr; }
|
||||
virtual std::unique_ptr<Echo> makeEcho() { return nullptr; }
|
||||
virtual Ipc* ipc() { return nullptr; }
|
||||
virtual bool canListenIpc() { return false; }
|
||||
};
|
||||
|
||||
//! Return implementation of Init interface for the node process. If the argv
|
||||
|
|
|
@ -525,7 +525,7 @@ int GuiMain(int argc, char* argv[])
|
|||
|
||||
/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
|
||||
// Command-line options take precedence:
|
||||
SetupServerArgs(gArgs);
|
||||
SetupServerArgs(gArgs, init->canListenIpc());
|
||||
SetupUIArgs(gArgs);
|
||||
std::string error;
|
||||
if (!gArgs.ParseParameters(argc, argv, error)) {
|
||||
|
|
|
@ -59,7 +59,7 @@ FUZZ_TARGET(system, .init = initialize_system)
|
|||
args_manager.SoftSetBoolArg(str_arg, f_value);
|
||||
},
|
||||
[&] {
|
||||
const OptionsCategory options_category = fuzzed_data_provider.PickValueInArray<OptionsCategory>({OptionsCategory::OPTIONS, OptionsCategory::CONNECTION, OptionsCategory::WALLET, OptionsCategory::WALLET_DEBUG_TEST, OptionsCategory::ZMQ, OptionsCategory::DEBUG_TEST, OptionsCategory::CHAINPARAMS, OptionsCategory::NODE_RELAY, OptionsCategory::BLOCK_CREATION, OptionsCategory::RPC, OptionsCategory::GUI, OptionsCategory::COMMANDS, OptionsCategory::REGISTER_COMMANDS, OptionsCategory::CLI_COMMANDS, OptionsCategory::HIDDEN});
|
||||
const OptionsCategory options_category = fuzzed_data_provider.PickValueInArray<OptionsCategory>({OptionsCategory::OPTIONS, OptionsCategory::CONNECTION, OptionsCategory::WALLET, OptionsCategory::WALLET_DEBUG_TEST, OptionsCategory::ZMQ, OptionsCategory::DEBUG_TEST, OptionsCategory::CHAINPARAMS, OptionsCategory::NODE_RELAY, OptionsCategory::BLOCK_CREATION, OptionsCategory::RPC, OptionsCategory::GUI, OptionsCategory::COMMANDS, OptionsCategory::REGISTER_COMMANDS, OptionsCategory::CLI_COMMANDS, OptionsCategory::IPC, OptionsCategory::HIDDEN});
|
||||
// Avoid hitting:
|
||||
// common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
|
||||
const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16));
|
||||
|
|
Loading…
Add table
Reference in a new issue