cli: modify -addrinfo to use getaddrmaninfo RPC endpoint

currently -addrinfo returns addresses known to the node after
filtering for quality and recency. However, the node considers
all known addresses (even the filtered out addresses) when
selecting peers to connect to.

So update -addrinfo to also display the full set of known
addresses for more useful node information.
This commit is contained in:
stratospher 2023-01-29 22:19:00 +05:30
parent 154b98a7aa
commit 675be93024

View File

@ -89,7 +89,7 @@ static void SetupCliArgs(ArgsManager& argsman)
"RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000",
DEFAULT_NBLOCKS, DEFAULT_MAX_TRIES),
ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);
argsman.AddArg("-addrinfo", "Get the number of addresses known to the node, per network and total, after filtering for quality and recency. The total number of addresses known to the node may be higher.", ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);
argsman.AddArg("-addrinfo", "Get the number of addresses known to the node, per network and total.", ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);
argsman.AddArg("-getinfo", "Get general information from the remote server. Note that unlike server-side RPC calls, the output of -getinfo is the result of multiple non-atomic requests. Some entries in the output may represent results from different states (e.g. wallet balance may be as of a different block from the chain state reported)", ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);
argsman.AddArg("-netinfo", strprintf("Get network peer connection information from the remote server. An optional argument from 0 to %d can be passed for different peers listings (default: 0). If a non-zero value is passed, an additional \"outonly\" (or \"o\") argument can be passed to see outbound peers only. Pass \"help\" (or \"h\") for detailed help documentation.", NETINFO_MAX_LEVEL), ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);
@ -279,33 +279,32 @@ struct AddrinfoRequestHandler : BaseRequestHandler {
if (!args.empty()) {
throw std::runtime_error("-addrinfo takes no arguments");
}
UniValue params{RPCConvertValues("getnodeaddresses", std::vector<std::string>{{"0"}})};
return JSONRPCRequestObj("getnodeaddresses", params, 1);
return JSONRPCRequestObj("getaddrmaninfo", NullUniValue, 1);
}
UniValue ProcessReply(const UniValue& reply) override
{
if (!reply["error"].isNull()) return reply;
const std::vector<UniValue>& nodes{reply["result"].getValues()};
if (!nodes.empty() && nodes.at(0)["network"].isNull()) {
throw std::runtime_error("-addrinfo requires bitcoind server to be running v22.0 and up");
}
// Count the number of peers known to our node, by network.
std::array<uint64_t, NETWORKS.size()> counts{{}};
for (const UniValue& node : nodes) {
std::string network_name{node["network"].get_str()};
const int8_t network_id{NetworkStringToId(network_name)};
if (network_id == UNKNOWN_NETWORK) continue;
++counts.at(network_id);
if (!reply["error"].isNull()) {
if (reply["error"]["code"].getInt<int>() == RPC_METHOD_NOT_FOUND) {
throw std::runtime_error("-addrinfo requires bitcoind v26.0 or later which supports getaddrmaninfo RPC. Please upgrade your node or use bitcoin-cli from the same version.");
}
return reply;
}
// Process getaddrmaninfo reply
const std::vector<std::string>& network_types{reply["result"].getKeys()};
const std::vector<UniValue>& addrman_counts{reply["result"].getValues()};
// Prepare result to return to user.
UniValue result{UniValue::VOBJ}, addresses{UniValue::VOBJ};
uint64_t total{0}; // Total address count
for (size_t i = 1; i < NETWORKS.size() - 1; ++i) {
addresses.pushKV(NETWORKS[i], counts.at(i));
total += counts.at(i);
for (size_t i = 0; i < network_types.size(); ++i) {
int addr_count = addrman_counts[i]["total"].getInt<int>();
if (network_types[i] == "all_networks") {
addresses.pushKV("total", addr_count);
} else {
addresses.pushKV(network_types[i], addr_count);
}
}
addresses.pushKV("total", total);
result.pushKV("addresses_known", std::move(addresses));
return JSONRPCReplyObj(std::move(result), NullUniValue, /*id=*/1, JSONRPCVersion::V2);
}