From 84934bf70e11fe4cda1cfda60113a54895d4fdd5 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Tue, 24 Nov 2020 13:59:33 -0500 Subject: 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. --- src/rpc/misc.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/rpc/misc.cpp') 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 #include #include +#include +#include +#include #include #include #include @@ -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 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) { -- cgit v1.2.3