Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251}},252{"exclude", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The categories to remove from debug logging",253{254{"exclude_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"},255}},256},257RPCResult{258RPCResult::Type::OBJ_DYN, "", "keys are the logging categories, and values indicates its status",259{260{RPCResult::Type::BOOL, "category", "if being debug logged or not. false:inactive, true:active"},261}262},263RPCExamples{264HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"")265+ HelpExampleRpc("logging", "[\"all\"], [\"leveldb\"]")266},267[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue268{269if (request.params[0].isArray()) {270EnableOrDisableLogCategories(request.params[0], true);271}272if (request.params[1].isArray()) {273EnableOrDisableLogCategories(request.params[1], false);274}276UniValue result(UniValue::VOBJ);277for (const auto& logCatActive : LogInstance().LogCategoriesList()) {278result.pushKV(logCatActive.category, logCatActive.active);279}281return result;282},283};284}286static RPCMethod echo(const std::string& name)287{288return RPCMethod{289name,290"Simply echo back the input arguments. This command is for testing.\n"291"\nIt will return an internal bug report when arg9='trigger_internal_bug' is passed.\n"292"\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in "293"bitcoin-cli and the GUI. There is no server-side difference.",294{295{"arg0", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},296{"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},297{"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},298{"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},299{"arg4", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},300{"arg5", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},301{"arg6", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},302{"arg7", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},303{"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},304{"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "", RPCArgOptions{.skip_type_check = true}},305},306RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},307RPCExamples{""},308[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue309{310if (request.params[9].isStr()) {311CHECK_NONFATAL(request.params[9].get_str() != "trigger_internal_bug");312}314return request.params;315},316};317}319static RPCMethod echo() { return echo("echo"); }320static RPCMethod echojson() { return echo("echojson"); }322static RPCMethod echoipc()323{324return RPCMethod{325"echoipc",326"Echo back the input argument, passing it through a spawned process in a multiprocess build.\n"327"This command is for testing.\n",328{{"arg", RPCArg::Type::STR, RPCArg::Optional::NO, "The string to echo",}},329RPCResult{RPCResult::Type::STR, "echo", "The echoed string."},330RPCExamples{HelpExampleCli("echo", "\"Hello world\"") +331HelpExampleRpc("echo", "\"Hello world\"")},332[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {333interfaces::Init& local_init = *EnsureAnyNodeContext(request.context).init;334std::unique_ptr<interfaces::Echo> echo;335if (interfaces::Ipc* ipc = local_init.ipc()) {336// Spawn a new bitcoin-node process and call makeEcho to get a337// client pointer to a interfaces::Echo instance running in338// that process. This is just for testing. A slightly more339// realistic test spawning a different executable instead of340// the same executable would add a new bitcoin-echo executable,341// and spawn bitcoin-echo below instead of bitcoin-node. But342// using bitcoin-node avoids the need to build and install a343// new executable just for this one test.344auto init = ipc->spawnProcess("bitcoin-node");345echo = init->makeEcho();346ipc->addCleanup(*echo, [init = init.release()] { delete init; });347} else {348// IPC support is not available because this is a bitcoind349// process not a bitcoind-node process, so just create a local350// interfaces::Echo object and return it so the `echoipc` RPC351// method will work, and the python test calling `echoipc`352// can expect the same result.353echo = local_init.makeEcho();354}355return echo->echo(request.params[0].get_str());356},357};358}360static UniValue SummaryToJSON(const IndexSummary&& summary, std::string index_name)361{362UniValue ret_summary(UniValue::VOBJ);363if (!index_name.empty() && index_name != summary.name) return ret_summary;365UniValue entry(UniValue::VOBJ);366entry.pushKV("synced", summary.synced);367entry.pushKV("best_block_height", summary.best_block_height);368ret_summary.pushKV(summary.name, std::move(entry));369return ret_summary;370}372static RPCMethod getindexinfo()373{374return RPCMethod{375"getindexinfo",376"Returns the status of one or all available indices currently running in the node.\n",377{378{"index_name", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Filter results for an index with a specific name."},379},380RPCResult{381RPCResult::Type::OBJ_DYN, "", "", {382{383RPCResult::Type::OBJ, "name", "The name of the index",384{385{RPCResult::Type::BOOL, "synced", "Whether the index is synced or not"},386{RPCResult::Type::NUM, "best_block_height", "The block height to which the index is synced"},387}388},389},390},391RPCExamples{392HelpExampleCli("getindexinfo", "")393+ HelpExampleRpc("getindexinfo", "")394+ HelpExampleCli("getindexinfo", "txindex")395+ HelpExampleRpc("getindexinfo", R"("txindex")")396},397[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue398{399UniValue result(UniValue::VOBJ);400const std::string index_name{self.MaybeArg<std::string_view>("index_name").value_or("")};402if (g_txindex) {403result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name));404}406if (g_coin_stats_index) {407result.pushKVs(SummaryToJSON(g_coin_stats_index->GetSummary(), index_name));408}410if (g_txospenderindex) {411result.pushKVs(SummaryToJSON(g_txospenderindex->GetSummary(), index_name));412}414ForEachBlockFilterIndex([&result, &index_name](const BlockFilterIndex& index) {415result.pushKVs(SummaryToJSON(index.GetSummary(), index_name));416});418return result;419},420};421}423void RegisterNodeRPCCommands(CRPCTable& t)424{425static const CRPCCommand commands[]{426{"control", &getmemoryinfo},427{"control", &logging},428{"util", &getindexinfo},429{"hidden", &setmocktime},430{"hidden", &mockscheduler},431{"hidden", &echo},432{"hidden", &echojson},433{"hidden", &echoipc},434};435for (const auto& c : commands) {436t.appendCommand(c.name, &c);437}438}