Skip to content

Commit db4d2c2

Browse files
committed
cli: create AddrinfoRequestHandler class
1 parent 4ad83a9 commit db4d2c2

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

src/bitcoin-cli.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
4242
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
4343
static const bool DEFAULT_NAMED=false;
4444
static const int CONTINUE_EXECUTION=-1;
45+
static constexpr int8_t UNKNOWN_NETWORK{-1};
4546

4647
/** Default number of blocks to generate for RPC generatetoaddress. */
4748
static const std::string DEFAULT_NBLOCKS = "1";
@@ -228,6 +229,56 @@ class BaseRequestHandler
228229
virtual UniValue ProcessReply(const UniValue &batch_in) = 0;
229230
};
230231

232+
/** Process addrinfo requests */
233+
class AddrinfoRequestHandler : public BaseRequestHandler
234+
{
235+
private:
236+
static constexpr uint8_t m_networks_size{5};
237+
const std::array<std::string, m_networks_size> m_networks{{"ipv4", "ipv6", "torv2", "torv3", "i2p"}};
238+
int8_t NetworkStringToId(const std::string& str) const
239+
{
240+
for (uint8_t i = 0; i < m_networks_size; ++i) {
241+
if (str == m_networks.at(i)) return i;
242+
}
243+
return UNKNOWN_NETWORK;
244+
}
245+
246+
public:
247+
UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
248+
{
249+
if (!args.empty()) {
250+
throw std::runtime_error("-addrinfo takes no arguments");
251+
}
252+
UniValue params{RPCConvertValues("getnodeaddresses", std::vector<std::string>{{"0"}})};
253+
return JSONRPCRequestObj("getnodeaddresses", params, 1);
254+
}
255+
256+
UniValue ProcessReply(const UniValue& reply) override
257+
{
258+
// Count the number of peers we know by network, including torv2 versus torv3.
259+
std::array<uint64_t, m_networks_size> counts{{}};
260+
for (const UniValue& node : reply["result"].getValues()) {
261+
std::string network_name{node["network"].get_str()};
262+
if (network_name == "onion") {
263+
network_name = node["address"].get_str().size() > 22 ? "torv3" : "torv2";
264+
}
265+
const int8_t network_id{NetworkStringToId(network_name)};
266+
if (network_id == UNKNOWN_NETWORK) continue;
267+
++counts.at(network_id);
268+
}
269+
// Prepare result to return to user.
270+
UniValue result{UniValue::VOBJ}, addresses{UniValue::VOBJ};
271+
uint64_t total{0}; // Total address count
272+
for (uint8_t i = 0; i < m_networks_size; ++i) {
273+
addresses.pushKV(m_networks.at(i), counts.at(i));
274+
total += counts.at(i);
275+
}
276+
addresses.pushKV("total", total);
277+
result.pushKV("addresses_known", addresses);
278+
return JSONRPCReplyObj(result, NullUniValue, 1);
279+
}
280+
};
281+
231282
/** Process getinfo requests */
232283
class GetinfoRequestHandler: public BaseRequestHandler
233284
{
@@ -299,7 +350,6 @@ class GetinfoRequestHandler: public BaseRequestHandler
299350
class NetinfoRequestHandler : public BaseRequestHandler
300351
{
301352
private:
302-
static constexpr int8_t UNKNOWN_NETWORK{-1};
303353
static constexpr uint8_t m_networks_size{4};
304354
static constexpr uint8_t MAX_DETAIL_LEVEL{4};
305355
const std::array<std::string, m_networks_size> m_networks{{"ipv4", "ipv6", "onion", "i2p"}};

0 commit comments

Comments
 (0)