diff options
author | Jon Atack <jon@atack.com> | 2021-04-01 10:46:20 +0200 |
---|---|---|
committer | Jon Atack <jon@atack.com> | 2021-04-09 09:02:04 +0200 |
commit | db4d2c282afd46709792aaf2d36ffbfc1745b776 (patch) | |
tree | a9aa45eccd51bc0c66775f5918c4c8c43f8b8a63 /src/bitcoin-cli.cpp | |
parent | 4ad83a9597e4f5340742d080e26437c5d8d203ba (diff) |
cli: create AddrinfoRequestHandler class
Diffstat (limited to 'src/bitcoin-cli.cpp')
-rw-r--r-- | src/bitcoin-cli.cpp | 52 |
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"}}; |