Skip to content

Commit e0f2037

Browse files
committed
cli: modify -addrinfo to display % of services the addresses support
1 parent aebfac1 commit e0f2037

File tree

1 file changed

+75
-5
lines changed

1 file changed

+75
-5
lines changed

src/bitcoin-cli.cpp

+75-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <common/system.h>
1212
#include <compat/compat.h>
1313
#include <compat/stdin.h>
14+
#include <logging.h>
1415
#include <policy/feerate.h>
1516
#include <rpc/client.h>
1617
#include <rpc/mining.h>
@@ -256,19 +257,28 @@ class BaseRequestHandler
256257
class AddrinfoRequestHandler : public BaseRequestHandler
257258
{
258259
public:
260+
const int ID_ADDRINFO = 0;
261+
const int ID_SERVICEINFO = 1;
262+
259263
UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
260264
{
261265
if (!args.empty()) {
262266
throw std::runtime_error("-addrinfo takes no arguments");
263267
}
264-
return JSONRPCRequestObj("getaddrmaninfo", NullUniValue, 1);
268+
UniValue result(UniValue::VARR);
269+
result.push_back(JSONRPCRequestObj("getaddrmaninfo", NullUniValue, ID_ADDRINFO));
270+
result.push_back(JSONRPCRequestObj("getrawaddrman", NullUniValue, ID_SERVICEINFO));
271+
return result;
265272
}
266273

267-
UniValue ProcessReply(const UniValue& reply) override
274+
UniValue ProcessReply(const UniValue& batch_in) override
268275
{
269-
if (!reply["error"].isNull()) return reply;
270-
const std::vector<std::string>& network_types{reply["result"].getKeys()};
271-
const std::vector<UniValue>& addrman_counts{reply["result"].getValues()};
276+
const std::vector<UniValue> batch{JSONRPCProcessBatchReply(batch_in)};
277+
if (!batch[ID_ADDRINFO]["error"].isNull()) return batch[ID_ADDRINFO];
278+
if (!batch[ID_SERVICEINFO]["error"].isNull()) return batch[ID_SERVICEINFO];
279+
280+
const std::vector<std::string>& network_types{batch[ID_ADDRINFO]["result"].getKeys()};
281+
const std::vector<UniValue>& addrman_counts{batch[ID_ADDRINFO]["result"].getValues()};
272282
if (network_types.empty()) {
273283
throw std::runtime_error("-addrinfo requires bitcoind server to be running v28.0 and up. if using an earlier bitcoind server (v22.0 - v27.0), use the appropriate binary");
274284
}
@@ -283,6 +293,66 @@ class AddrinfoRequestHandler : public BaseRequestHandler
283293
}
284294
addresses.pushKV("total", total);
285295
result.pushKV("addresses_known", addresses);
296+
297+
const std::vector<std::string>& table_names{batch[ID_SERVICEINFO]["result"].getKeys()};
298+
const std::vector<UniValue>& table_entries{batch[ID_SERVICEINFO]["result"].getValues()};
299+
300+
UniValue services(UniValue::VOBJ);
301+
int t_count_network = 0, t_count_bloom = 0, t_count_witness = 0, t_count_compact_filter = 0, t_count_network_limited = 0, t_count_v2 = 0;
302+
for (size_t i = 0; i < table_entries.size(); ++i) {
303+
const UniValue& entry = table_entries[i];
304+
int count_network = 0, count_bloom = 0, count_witness = 0, count_compact_filter = 0, count_network_limited = 0, count_v2 = 0;
305+
306+
for (const UniValue& bucket_position : entry.getValues()) {
307+
uint64_t services = bucket_position["services"].getInt<uint64_t>();
308+
if (services & (1 << 0)){
309+
count_network++;
310+
}
311+
if (services & (1 << 2)){
312+
count_bloom++;
313+
}
314+
if (services & (1 << 3)){
315+
count_witness++;
316+
}
317+
if (services & (1 << 6)){
318+
count_compact_filter++;
319+
}
320+
if (services & (1 << 10)){
321+
count_network_limited++;
322+
}
323+
if (services & (1 << 11)){
324+
count_v2++;
325+
}
326+
}
327+
UniValue service_from_table(UniValue::VOBJ);
328+
double frac = 100/double(count_network + count_bloom + count_witness + count_compact_filter + count_network_limited + count_v2);
329+
service_from_table.pushKV("% of NODE_NETWORK", count_network*frac);
330+
service_from_table.pushKV("% of NODE_BLOOM", count_bloom*frac);
331+
service_from_table.pushKV("% of NODE_WITNESS", count_witness*frac);
332+
service_from_table.pushKV("% of NODE_COMPACT_FILTERS", count_compact_filter*frac);
333+
service_from_table.pushKV("% of NODE_NETWORK_LIMITED", count_network_limited*frac);
334+
service_from_table.pushKV("% of NODE_P2P_V2", count_v2*frac);
335+
services.pushKV(table_names[i], service_from_table);
336+
337+
t_count_network += count_network;
338+
t_count_bloom += count_bloom;
339+
t_count_witness += count_witness;
340+
t_count_compact_filter += count_compact_filter;
341+
t_count_network_limited += count_network_limited;
342+
t_count_v2 += count_v2;
343+
}
344+
345+
UniValue service_from_table(UniValue::VOBJ);
346+
double frac = 100/double(t_count_network + t_count_bloom + t_count_witness + t_count_compact_filter + t_count_network_limited + t_count_v2);
347+
service_from_table.pushKV("% of NODE_NETWORK", t_count_network*frac);
348+
service_from_table.pushKV("% of NODE_BLOOM", t_count_bloom*frac);
349+
service_from_table.pushKV("% of NODE_WITNESS", t_count_witness*frac);
350+
service_from_table.pushKV("% of NODE_COMPACT_FILTERS", t_count_compact_filter*frac);
351+
service_from_table.pushKV("% of NODE_NETWORK_LIMITED", t_count_network_limited*frac);
352+
service_from_table.pushKV("% of NODE_P2P_V2", t_count_v2*frac);
353+
services.pushKV("TOTAL", service_from_table);
354+
355+
result.pushKV("services", services);
286356
return JSONRPCReplyObj(result, NullUniValue, 1);
287357
}
288358
};

0 commit comments

Comments
 (0)