aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/misc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc/misc.cpp')
-rw-r--r--src/rpc/misc.cpp68
1 files changed, 57 insertions, 11 deletions
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 143be1274e..ab239fe79c 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -5,8 +5,12 @@
#include <httpserver.h>
#include <index/blockfilterindex.h>
+#include <index/coinstatsindex.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>
@@ -17,7 +21,6 @@
#include <script/descriptor.h>
#include <util/check.h>
#include <util/message.h> // For MessageSign(), MessageVerify()
-#include <util/ref.h>
#include <util/strencodings.h>
#include <util/system.h>
@@ -91,7 +94,7 @@ static RPCHelpMan createmultisig()
{
{"key", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hex-encoded public key"},
}},
- {"address_type", RPCArg::Type::STR, /* default */ "legacy", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
+ {"address_type", RPCArg::Type::STR, RPCArg::Default{"legacy"}, "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
@@ -391,8 +394,9 @@ static RPCHelpMan setmocktime()
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime can not be negative: %s.", time));
}
SetMockTime(time);
- if (request.context.Has<NodeContext>()) {
- for (const auto& chain_client : request.context.Get<NodeContext>().chain_clients) {
+ auto node_context = util::AnyPtr<NodeContext>(request.context);
+ if (node_context) {
+ for (const auto& chain_client : node_context->chain_clients) {
chain_client->setMockTime(time);
}
}
@@ -420,15 +424,15 @@ static RPCHelpMan mockscheduler()
// check params are valid values
RPCTypeCheck(request.params, {UniValue::VNUM});
int64_t delta_seconds = request.params[0].get_int64();
- if ((delta_seconds <= 0) || (delta_seconds > 3600)) {
+ if (delta_seconds <= 0 || delta_seconds > 3600) {
throw std::runtime_error("delta_time must be between 1 and 3600 seconds (1 hr)");
}
+ auto node_context = util::AnyPtr<NodeContext>(request.context);
// protect against null pointer dereference
- CHECK_NONFATAL(request.context.Has<NodeContext>());
- NodeContext& node = request.context.Get<NodeContext>();
- CHECK_NONFATAL(node.scheduler);
- node.scheduler->MockForward(std::chrono::seconds(delta_seconds));
+ CHECK_NONFATAL(node_context);
+ CHECK_NONFATAL(node_context->scheduler);
+ node_context->scheduler->MockForward(std::chrono::seconds(delta_seconds));
return NullUniValue;
},
@@ -475,7 +479,7 @@ static RPCHelpMan getmemoryinfo()
return RPCHelpMan{"getmemoryinfo",
"Returns an object containing information about memory usage.\n",
{
- {"mode", RPCArg::Type::STR, /* default */ "\"stats\"", "determines what kind of information is returned.\n"
+ {"mode", RPCArg::Type::STR, RPCArg::Default{"stats"}, "determines what kind of information is returned.\n"
" - \"stats\" returns general statistics about memory usage in the daemon.\n"
" - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc 2.10+)."},
},
@@ -628,7 +632,7 @@ static RPCHelpMan echo(const std::string& name)
{"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
{"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
},
- RPCResult{RPCResult::Type::NONE, "", "Returns whatever was passed in"},
+ RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
@@ -644,6 +648,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);
@@ -689,6 +730,10 @@ static RPCHelpMan getindexinfo()
result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name));
}
+ if (g_coin_stats_index) {
+ result.pushKVs(SummaryToJSON(g_coin_stats_index->GetSummary(), index_name));
+ }
+
ForEachBlockFilterIndex([&result, &index_name](const BlockFilterIndex& index) {
result.pushKVs(SummaryToJSON(index.GetSummary(), index_name));
});
@@ -719,6 +764,7 @@ static const CRPCCommand commands[] =
{ "hidden", &mockscheduler, },
{ "hidden", &echo, },
{ "hidden", &echojson, },
+ { "hidden", &echoipc, },
};
// clang-format on
for (const auto& c : commands) {