mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
ipc: Expose an RPC interface over the -ipcbind socket
This allows `bitcoin-cli` to connect to the node via IPC instead TCP to execute RPC methods in an upcoming commit.
This commit is contained in:
@@ -719,7 +719,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
||||
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the maximum 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);
|
||||
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. Enabling this gives local processes that can access the socket unauthenticated RPC access, so it's important to choose a path with secure permissions if customizing this.", ArgsManager::ALLOW_ANY, OptionsCategory::IPC);
|
||||
}
|
||||
|
||||
#if HAVE_DECL_FORK
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <interfaces/init.h>
|
||||
#include <interfaces/ipc.h>
|
||||
#include <interfaces/node.h>
|
||||
#include <interfaces/rpc.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <node/context.h>
|
||||
#include <util/check.h>
|
||||
@@ -33,6 +34,7 @@ public:
|
||||
return MakeWalletLoader(chain, *Assert(m_node.args));
|
||||
}
|
||||
std::unique_ptr<interfaces::Echo> makeEcho() override { return interfaces::MakeEcho(); }
|
||||
std::unique_ptr<interfaces::Rpc> makeRpc() override { return interfaces::MakeRpc(m_node); }
|
||||
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
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <interfaces/init.h>
|
||||
#include <interfaces/ipc.h>
|
||||
#include <interfaces/node.h>
|
||||
#include <interfaces/rpc.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <node/context.h>
|
||||
#include <util/check.h>
|
||||
@@ -36,6 +37,7 @@ public:
|
||||
return MakeWalletLoader(chain, *Assert(m_node.args));
|
||||
}
|
||||
std::unique_ptr<interfaces::Echo> makeEcho() override { return interfaces::MakeEcho(); }
|
||||
std::unique_ptr<interfaces::Rpc> makeRpc() override { return interfaces::MakeRpc(m_node); }
|
||||
interfaces::Ipc* ipc() override { return m_ipc.get(); }
|
||||
bool canListenIpc() override { return true; }
|
||||
const char* exeName() override { return EXE_NAME; }
|
||||
|
||||
@@ -16,4 +16,6 @@ The following interfaces are defined here:
|
||||
|
||||
* [`Ipc`](ipc.h) — used by multiprocess code to access `Init` interface across processes. Added in [#19160](https://github.com/bitcoin/bitcoin/pull/19160).
|
||||
|
||||
* [`Rpc`](rpc.h) — used by `bitcoin-cli` to be able to call RPC methods over a unix socket instead of TCP.
|
||||
|
||||
The interfaces above define boundaries between major components of bitcoin code (node, wallet, and gui), making it possible for them to run in [different processes](../../doc/multiprocess.md), and be tested, developed, and understood independently. These interfaces are not currently designed to be stable or to be used externally.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <interfaces/echo.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <interfaces/node.h>
|
||||
#include <interfaces/rpc.h>
|
||||
#include <interfaces/wallet.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -36,6 +37,7 @@ public:
|
||||
virtual std::unique_ptr<Mining> makeMining() { return nullptr; }
|
||||
virtual std::unique_ptr<WalletLoader> makeWalletLoader(Chain& chain) { return nullptr; }
|
||||
virtual std::unique_ptr<Echo> makeEcho() { return nullptr; }
|
||||
virtual std::unique_ptr<Rpc> makeRpc() { return nullptr; }
|
||||
virtual Ipc* ipc() { return nullptr; }
|
||||
virtual bool canListenIpc() { return false; }
|
||||
virtual const char* exeName() { return nullptr; }
|
||||
|
||||
31
src/interfaces/rpc.h
Normal file
31
src/interfaces/rpc.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2025 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_INTERFACES_RPC_H
|
||||
#define BITCOIN_INTERFACES_RPC_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class UniValue;
|
||||
|
||||
namespace node {
|
||||
struct NodeContext;
|
||||
} // namespace node
|
||||
|
||||
namespace interfaces {
|
||||
//! Interface giving clients ability to emulate HTTP RPC calls.
|
||||
class Rpc
|
||||
{
|
||||
public:
|
||||
virtual ~Rpc() = default;
|
||||
virtual UniValue executeRpc(UniValue request, std::string url, std::string user) = 0;
|
||||
};
|
||||
|
||||
//! Return implementation of Rpc interface.
|
||||
std::unique_ptr<Rpc> MakeRpc(node::NodeContext& node);
|
||||
|
||||
} // namespace interfaces
|
||||
|
||||
#endif // BITCOIN_INTERFACES_RPC_H
|
||||
@@ -14,6 +14,7 @@ target_capnp_sources(bitcoin_ipc ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
capnp/echo.capnp
|
||||
capnp/init.capnp
|
||||
capnp/mining.capnp
|
||||
capnp/rpc.capnp
|
||||
)
|
||||
|
||||
target_link_libraries(bitcoin_ipc
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
|
||||
#include <ipc/capnp/echo.capnp.proxy-types.h>
|
||||
#include <ipc/capnp/mining.capnp.proxy-types.h>
|
||||
#include <ipc/capnp/rpc.capnp.proxy-types.h>
|
||||
|
||||
#endif // BITCOIN_IPC_CAPNP_INIT_TYPES_H
|
||||
|
||||
@@ -15,11 +15,13 @@ $Proxy.includeTypes("ipc/capnp/init-types.h");
|
||||
|
||||
using Echo = import "echo.capnp";
|
||||
using Mining = import "mining.capnp";
|
||||
using Rpc = import "rpc.capnp";
|
||||
|
||||
interface Init $Proxy.wrap("interfaces::Init") {
|
||||
construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap);
|
||||
makeEcho @1 (context :Proxy.Context) -> (result :Echo.Echo);
|
||||
makeMining @3 (context :Proxy.Context) -> (result :Mining.Mining);
|
||||
makeRpc @4 (context :Proxy.Context) -> (result :Rpc.Rpc);
|
||||
|
||||
# DEPRECATED: no longer supported; server returns an error.
|
||||
makeMiningOld2 @2 () -> ();
|
||||
|
||||
12
src/ipc/capnp/rpc-types.h
Normal file
12
src/ipc/capnp/rpc-types.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2025 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_IPC_CAPNP_RPC_TYPES_H
|
||||
#define BITCOIN_IPC_CAPNP_RPC_TYPES_H
|
||||
|
||||
#include <ipc/capnp/common.capnp.proxy-types.h>
|
||||
#include <ipc/capnp/common-types.h>
|
||||
#include <ipc/capnp/rpc.capnp.proxy.h>
|
||||
|
||||
#endif // BITCOIN_IPC_CAPNP_RPC_TYPES_H
|
||||
17
src/ipc/capnp/rpc.capnp
Normal file
17
src/ipc/capnp/rpc.capnp
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2025 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@0x9c3505dc45e146ac;
|
||||
|
||||
using Cxx = import "/capnp/c++.capnp";
|
||||
$Cxx.namespace("ipc::capnp::messages");
|
||||
|
||||
using Common = import "common.capnp";
|
||||
using Proxy = import "/mp/proxy.capnp";
|
||||
$Proxy.include("interfaces/rpc.h");
|
||||
$Proxy.includeTypes("ipc/capnp/rpc-types.h");
|
||||
|
||||
interface Rpc $Proxy.wrap("interfaces::Rpc") {
|
||||
executeRpc @0 (context :Proxy.Context, request :Text, uri :Text, user :Text) -> (result :Text);
|
||||
}
|
||||
@@ -12,12 +12,14 @@
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <external_signer.h>
|
||||
#include <httprpc.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <init.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <interfaces/handler.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <interfaces/node.h>
|
||||
#include <interfaces/rpc.h>
|
||||
#include <interfaces/types.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <kernel/chain.h>
|
||||
@@ -81,6 +83,7 @@ using interfaces::Handler;
|
||||
using interfaces::MakeSignalHandler;
|
||||
using interfaces::Mining;
|
||||
using interfaces::Node;
|
||||
using interfaces::Rpc;
|
||||
using interfaces::WalletLoader;
|
||||
using kernel::ChainstateRole;
|
||||
using node::BlockAssembler;
|
||||
@@ -1011,6 +1014,24 @@ public:
|
||||
bool m_interrupt_mining{false};
|
||||
NodeContext& m_node;
|
||||
};
|
||||
|
||||
class RpcImpl : public Rpc
|
||||
{
|
||||
public:
|
||||
explicit RpcImpl(NodeContext& node) : m_node(node) {}
|
||||
|
||||
UniValue executeRpc(UniValue request, std::string uri, std::string user) override
|
||||
{
|
||||
JSONRPCRequest req;
|
||||
req.context = &m_node;
|
||||
req.URI = std::move(uri);
|
||||
req.authUser = std::move(user);
|
||||
HTTPStatusCode status;
|
||||
return ExecuteHTTPRPC(request, req, status);
|
||||
}
|
||||
|
||||
NodeContext& m_node;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace node
|
||||
|
||||
@@ -1030,4 +1051,5 @@ std::unique_ptr<Mining> MakeMining(node::NodeContext& context, bool wait_loaded)
|
||||
}
|
||||
return std::make_unique<node::MinerImpl>(context);
|
||||
}
|
||||
std::unique_ptr<Rpc> MakeRpc(node::NodeContext& context) { return std::make_unique<node::RpcImpl>(context); }
|
||||
} // namespace interfaces
|
||||
|
||||
Reference in New Issue
Block a user