@@ -256,19 +256,28 @@ class BaseRequestHandler
256
256
class AddrinfoRequestHandler : public BaseRequestHandler
257
257
{
258
258
public:
259
+ const int ID_ADDRINFO = 0 ;
260
+ const int ID_SERVICEINFO = 1 ;
261
+
259
262
UniValue PrepareRequest (const std::string& method, const std::vector<std::string>& args) override
260
263
{
261
264
if (!args.empty ()) {
262
265
throw std::runtime_error (" -addrinfo takes no arguments" );
263
266
}
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;
265
271
}
266
272
267
- UniValue ProcessReply (const UniValue& reply ) override
273
+ UniValue ProcessReply (const UniValue& batch_in ) override
268
274
{
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 ()};
272
281
if (network_types.empty ()) {
273
282
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" );
274
283
}
@@ -283,6 +292,66 @@ class AddrinfoRequestHandler : public BaseRequestHandler
283
292
}
284
293
addresses.pushKV (" total" , total);
285
294
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);
286
355
return JSONRPCReplyObj (result, NullUniValue, 1 );
287
356
}
288
357
};
0 commit comments