aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2020-11-24 13:59:33 -0500
committerRussell Yanofsky <russ@yanofsky.org>2021-04-23 03:02:50 -0500
commit84934bf70e11fe4cda1cfda60113a54895d4fdd5 (patch)
treea76e8bd27d3e32a9f433d6f24857d6b96e499efc /src/rpc
parent7d76cf667eff512043a28d4407cc89f58796c42b (diff)
downloadbitcoin-84934bf70e11fe4cda1cfda60113a54895d4fdd5.tar.xz
multiprocess: Add echoipc RPC method and test
Add simple interfaces::Echo IPC interface with one method that just takes and returns a string, to test multiprocess framework and provide an example of how it can be used to spawn and call between processes.
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/misc.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 00a06260ea..09b32345a2 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -7,6 +7,9 @@
#include <index/blockfilterindex.h>
#include <index/txindex.h>
#include <interfaces/chain.h>
+#include <interfaces/echo.h>
+#include <interfaces/init.h>
+#include <interfaces/ipc.h>
#include <key_io.h>
#include <node/context.h>
#include <outputtype.h>
@@ -644,6 +647,43 @@ static RPCHelpMan echo(const std::string& name)
static RPCHelpMan echo() { return echo("echo"); }
static RPCHelpMan echojson() { return echo("echojson"); }
+static RPCHelpMan echoipc()
+{
+ return RPCHelpMan{
+ "echoipc",
+ "\nEcho back the input argument, passing it through a spawned process in a multiprocess build.\n"
+ "This command is for testing.\n",
+ {{"arg", RPCArg::Type::STR, RPCArg::Optional::NO, "The string to echo",}},
+ RPCResult{RPCResult::Type::STR, "echo", "The echoed string."},
+ RPCExamples{HelpExampleCli("echo", "\"Hello world\"") +
+ HelpExampleRpc("echo", "\"Hello world\"")},
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
+ std::unique_ptr<interfaces::Echo> echo;
+ if (interfaces::Ipc* ipc = Assert(EnsureAnyNodeContext(request.context).init)->ipc()) {
+ // Spawn a new bitcoin-node process and call makeEcho to get a
+ // client pointer to a interfaces::Echo instance running in
+ // that process. This is just for testing. A slightly more
+ // realistic test spawning a different executable instead of
+ // the same executable would add a new bitcoin-echo executable,
+ // and spawn bitcoin-echo below instead of bitcoin-node. But
+ // using bitcoin-node avoids the need to build and install a
+ // new executable just for this one test.
+ auto init = ipc->spawnProcess("bitcoin-node");
+ echo = init->makeEcho();
+ ipc->addCleanup(*echo, [init = init.release()] { delete init; });
+ } else {
+ // IPC support is not available because this is a bitcoind
+ // process not a bitcoind-node process, so just create a local
+ // interfaces::Echo object and return it so the `echoipc` RPC
+ // method will work, and the python test calling `echoipc`
+ // can expect the same result.
+ echo = interfaces::MakeEcho();
+ }
+ return echo->echo(request.params[0].get_str());
+ },
+ };
+}
+
static UniValue SummaryToJSON(const IndexSummary&& summary, std::string index_name)
{
UniValue ret_summary(UniValue::VOBJ);
@@ -719,6 +759,7 @@ static const CRPCCommand commands[] =
{ "hidden", &mockscheduler, },
{ "hidden", &echo, },
{ "hidden", &echojson, },
+ { "hidden", &echoipc, },
};
// clang-format on
for (const auto& c : commands) {