Skip to content

Commit d55163f

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

File tree

1 file changed

+74
-5
lines changed

1 file changed

+74
-5
lines changed

src/bitcoin-cli.cpp

+74-5
Original file line numberDiff line numberDiff line change
@@ -256,19 +256,28 @@ class BaseRequestHandler
256256
class AddrinfoRequestHandler : public BaseRequestHandler
257257
{
258258
public:
259+
const int ID_ADDRINFO = 0;
260+
const int ID_SERVICEINFO = 1;
261+
259262
UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
260263
{
261264
if (!args.empty()) {
262265
throw std::runtime_error("-addrinfo takes no arguments");
263266
}
264-
return JSONRPCRequestObj("getaddrmaninfo", NullUniValue, 1);
267+
UniValue result(UniValue::VARR);
268+
result.push_back(JSONRPCRequestObj("getaddrmaninfo", NullUniValue, ID_ADDRINFO));
269+
result.push_back(JSONRPCRequestObj("getrawaddrman", NullUniValue, ID_SERVICEINFO));
270+
return result;
265271
}
266272

267-
UniValue ProcessReply(const UniValue& reply) override
273+
UniValue ProcessReply(const UniValue& batch_in) override
268274
{
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()};
275+
const std::vector<UniValue> batch{JSONRPCProcessBatchReply(batch_in)};
276+
if (!batch[ID_ADDRINFO]["error"].isNull()) return batch[ID_ADDRINFO];
277+
if (!batch[ID_SERVICEINFO]["error"].isNull()) return batch[ID_SERVICEINFO];
278+
279+
const std::vector<std::string>& network_types{batch[ID_ADDRINFO]["result"].getKeys()};
280+
const std::vector<UniValue>& addrman_counts{batch[ID_ADDRINFO]["result"].getValues()};
272281
if (network_types.empty()) {
273282
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");
274283
}
@@ -283,6 +292,66 @@ class AddrinfoRequestHandler : public BaseRequestHandler
283292
}
284293
addresses.pushKV("total", total);
285294
result.pushKV("addresses_known", addresses);
295+
296+
const std::vector<std::string>& table_names{batch[ID_SERVICEINFO]["result"].getKeys()};
297+
const std::vector<UniValue>& table_entries{batch[ID_SERVICEINFO]["result"].getValues()};
298+
299+
UniValue services(UniValue::VOBJ);
300+
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;
301+
for (size_t i = 0; i < table_entries.size(); ++i) {
302+
const UniValue& entry = table_entries[i];
303+
int count_network = 0, count_bloom = 0, count_witness = 0, count_compact_filter = 0, count_network_limited = 0, count_v2 = 0;
304+
305+
for (const UniValue& bucket_position : entry.getValues()) {
306+
uint64_t services = bucket_position["services"].getInt<uint64_t>();
307+
if (services & (1 << 0)){
308+
count_network++;
309+
}
310+
if (services & (1 << 2)){
311+
count_bloom++;
312+
}
313+
if (services & (1 << 3)){
314+
count_witness++;
315+
}
316+
if (services & (1 << 6)){
317+
count_compact_filter++;
318+
}
319+
if (services & (1 << 10)){
320+
count_network_limited++;
321+
}
322+
if (services & (1 << 11)){
323+
count_v2++;
324+
}
325+
}
326+
UniValue service_from_table(UniValue::VOBJ);
327+
double frac = 100/double(count_network + count_bloom + count_witness + count_compact_filter + count_network_limited + count_v2);
328+
service_from_table.pushKV("% of NODE_NETWORK", count_network*frac);
329+
service_from_table.pushKV("% of NODE_BLOOM", count_bloom*frac);
330+
service_from_table.pushKV("% of NODE_WITNESS", count_witness*frac);
331+
service_from_table.pushKV("% of NODE_COMPACT_FILTERS", count_compact_filter*frac);
332+
service_from_table.pushKV("% of NODE_NETWORK_LIMITED", count_network_limited*frac);
333+
service_from_table.pushKV("% of NODE_P2P_V2", count_v2*frac);
334+
services.pushKV(table_names[i], service_from_table);
335+
336+
t_count_network += count_network;
337+
t_count_bloom += count_bloom;
338+
t_count_witness += count_witness;
339+
t_count_compact_filter += count_compact_filter;
340+
t_count_network_limited += count_network_limited;
341+
t_count_v2 += count_v2;
342+
}
343+
344+
UniValue service_from_table(UniValue::VOBJ);
345+
double frac = 100/double(t_count_network + t_count_bloom + t_count_witness + t_count_compact_filter + t_count_network_limited + t_count_v2);
346+
service_from_table.pushKV("% of NODE_NETWORK", t_count_network*frac);
347+
service_from_table.pushKV("% of NODE_BLOOM", t_count_bloom*frac);
348+
service_from_table.pushKV("% of NODE_WITNESS", t_count_witness*frac);
349+
service_from_table.pushKV("% of NODE_COMPACT_FILTERS", t_count_compact_filter*frac);
350+
service_from_table.pushKV("% of NODE_NETWORK_LIMITED", t_count_network_limited*frac);
351+
service_from_table.pushKV("% of NODE_P2P_V2", t_count_v2*frac);
352+
services.pushKV("TOTAL", service_from_table);
353+
354+
result.pushKV("services", services);
286355
return JSONRPCReplyObj(result, NullUniValue, 1);
287356
}
288357
};

0 commit comments

Comments
 (0)