aboutsummaryrefslogtreecommitdiff
path: root/src/bitcoin-cli.cpp
diff options
context:
space:
mode:
authorJon Atack <jon@atack.com>2021-04-01 10:46:20 +0200
committerJon Atack <jon@atack.com>2021-04-09 09:02:04 +0200
commitdb4d2c282afd46709792aaf2d36ffbfc1745b776 (patch)
treea9aa45eccd51bc0c66775f5918c4c8c43f8b8a63 /src/bitcoin-cli.cpp
parent4ad83a9597e4f5340742d080e26437c5d8d203ba (diff)
cli: create AddrinfoRequestHandler class
Diffstat (limited to 'src/bitcoin-cli.cpp')
-rw-r--r--src/bitcoin-cli.cpp52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 4f3d7a4ffe..3b0caef39a 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -42,6 +42,7 @@ static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
static const bool DEFAULT_NAMED=false;
static const int CONTINUE_EXECUTION=-1;
+static constexpr int8_t UNKNOWN_NETWORK{-1};
/** Default number of blocks to generate for RPC generatetoaddress. */
static const std::string DEFAULT_NBLOCKS = "1";
@@ -228,6 +229,56 @@ public:
virtual UniValue ProcessReply(const UniValue &batch_in) = 0;
};
+/** Process addrinfo requests */
+class AddrinfoRequestHandler : public BaseRequestHandler
+{
+private:
+ static constexpr uint8_t m_networks_size{5};
+ const std::array<std::string, m_networks_size> m_networks{{"ipv4", "ipv6", "torv2", "torv3", "i2p"}};
+ int8_t NetworkStringToId(const std::string& str) const
+ {
+ for (uint8_t i = 0; i < m_networks_size; ++i) {
+ if (str == m_networks.at(i)) return i;
+ }
+ return UNKNOWN_NETWORK;
+ }
+
+public:
+ UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
+ {
+ 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);
+ }
+
+ UniValue ProcessReply(const UniValue& reply) override
+ {
+ // Count the number of peers we know by network, including torv2 versus torv3.
+ std::array<uint64_t, m_networks_size> counts{{}};
+ for (const UniValue& node : reply["result"].getValues()) {
+ std::string network_name{node["network"].get_str()};
+ if (network_name == "onion") {
+ network_name = node["address"].get_str().size() > 22 ? "torv3" : "torv2";
+ }
+ const int8_t network_id{NetworkStringToId(network_name)};
+ if (network_id == UNKNOWN_NETWORK) continue;
+ ++counts.at(network_id);
+ }
+ // Prepare result to return to user.
+ UniValue result{UniValue::VOBJ}, addresses{UniValue::VOBJ};
+ uint64_t total{0}; // Total address count
+ for (uint8_t i = 0; i < m_networks_size; ++i) {
+ addresses.pushKV(m_networks.at(i), counts.at(i));
+ total += counts.at(i);
+ }
+ addresses.pushKV("total", total);
+ result.pushKV("addresses_known", addresses);
+ return JSONRPCReplyObj(result, NullUniValue, 1);
+ }
+};
+
/** Process getinfo requests */
class GetinfoRequestHandler: public BaseRequestHandler
{
@@ -299,7 +350,6 @@ public:
class NetinfoRequestHandler : public BaseRequestHandler
{
private:
- static constexpr int8_t UNKNOWN_NETWORK{-1};
static constexpr uint8_t m_networks_size{4};
static constexpr uint8_t MAX_DETAIL_LEVEL{4};
const std::array<std::string, m_networks_size> m_networks{{"ipv4", "ipv6", "onion", "i2p"}};