Skip to content

Commit 2200b78

Browse files
committed
merge bitcoin#20877: user help and argument parsing improvements
1 parent bd934c7 commit 2200b78

File tree

1 file changed

+67
-72
lines changed

1 file changed

+67
-72
lines changed

src/bitcoin-cli.cpp

Lines changed: 67 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,6 @@ class GetinfoRequestHandler: public BaseRequestHandler
374374
class NetinfoRequestHandler : public BaseRequestHandler
375375
{
376376
private:
377-
static constexpr int8_t NET_I2P{3}; // pos of "i2p" in m_networks
378377
static constexpr uint8_t MAX_DETAIL_LEVEL{4};
379378
static constexpr std::array m_networks{"ipv4", "ipv6", "onion", "i2p"};
380379
std::array<std::array<uint16_t, m_networks.size() + 1>, 3> m_counts{{{}}}; //!< Peer counts by (in/out/total, networks/total)
@@ -387,13 +386,11 @@ class NetinfoRequestHandler : public BaseRequestHandler
387386
}
388387
return UNKNOWN_NETWORK;
389388
}
390-
uint8_t m_details_level{0}; //!< Optional user-supplied arg to set dashboard details level
391-
bool m_is_help_requested{false}; //!< Optional user-supplied arg to print help documentation
389+
uint8_t m_details_level{0}; //!< Optional user-supplied arg to set dashboard details level
392390
bool DetailsRequested() const { return m_details_level > 0 && m_details_level < 5; }
393391
bool IsAddressSelected() const { return m_details_level == 2 || m_details_level == 4; }
394392
bool IsVersionSelected() const { return m_details_level == 3 || m_details_level == 4; }
395393
bool m_is_asmap_on{false};
396-
bool m_is_i2p_on{false};
397394
size_t m_max_addr_length{0};
398395
size_t m_max_age_length{4};
399396
size_t m_max_id_length{2};
@@ -438,65 +435,6 @@ class NetinfoRequestHandler : public BaseRequestHandler
438435
if (conn_type == "addr-fetch") return "addr";
439436
return "";
440437
}
441-
const UniValue NetinfoHelp()
442-
{
443-
return std::string{
444-
"-netinfo level|\"help\" \n\n"
445-
"Returns a network peer connections dashboard with information from the remote server.\n"
446-
"Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n"
447-
"An optional integer argument from 0 to 4 can be passed for different peers listings.\n"
448-
"Pass \"help\" to see this detailed help documentation.\n"
449-
"If more than one argument is passed, only the first one is read and parsed.\n"
450-
"Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n"
451-
"Arguments:\n"
452-
"1. level (integer 0-4, optional) Specify the info level of the peers dashboard (default 0):\n"
453-
" 0 - Connection counts and local addresses\n"
454-
" 1 - Like 0 but with a peers listing (without address or version columns)\n"
455-
" 2 - Like 1 but with an address column\n"
456-
" 3 - Like 1 but with a version column\n"
457-
" 4 - Like 1 but with both address and version columns\n"
458-
"2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n"
459-
"Result:\n\n"
460-
"* The peers listing in levels 1-4 displays all of the peers sorted by direction and minimum ping time:\n\n"
461-
" Column Description\n"
462-
" ------ -----------\n"
463-
" <-> Direction\n"
464-
" \"in\" - inbound connections are those initiated by the peer\n"
465-
" \"out\" - outbound connections are those initiated by us\n"
466-
" type Type of peer connection\n"
467-
" \"full\" - full relay, the default\n"
468-
" \"block\" - block relay; like full relay but does not relay transactions or addresses\n"
469-
" \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n"
470-
" \"feeler\" - short-lived connection for testing addresses\n"
471-
" \"addr\" - address fetch; short-lived connection for requesting addresses\n"
472-
" net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", or \"cjdns\")\n"
473-
" mping Minimum observed ping time, in milliseconds (ms)\n"
474-
" ping Last observed ping time, in milliseconds (ms)\n"
475-
" send Time since last message sent to the peer, in seconds\n"
476-
" recv Time since last message received from the peer, in seconds\n"
477-
" txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n"
478-
" blk Time since last novel block passing initial validity checks received from the peer, in minutes\n"
479-
" age Duration of connection to the peer, in minutes\n"
480-
" asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n"
481-
" peer selection (only displayed if the -asmap config option is set)\n"
482-
" id Peer index, in increasing order of peer connections since node startup\n"
483-
" address IP address and port of the peer\n"
484-
" version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n"
485-
"* The connection counts table displays the number of peers by direction, network, and the totals\n"
486-
" for each, as well as two special outbound columns for block relay peers and manual peers.\n\n"
487-
"* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n"
488-
"Examples:\n\n"
489-
"Connection counts and local addresses only\n"
490-
"> dash-cli -netinfo\n\n"
491-
"Compact peers listing\n"
492-
"> dash-cli -netinfo 1\n\n"
493-
"Full dashboard\n"
494-
"> dash-cli -netinfo 4\n\n"
495-
"Full live dashboard, adjust --interval or --no-title as needed (Linux)\n"
496-
"> watch --interval 1 --no-title dash-cli -netinfo 4\n\n"
497-
"See this help\n"
498-
"> dash-cli -netinfo help\n"};
499-
}
500438
const int64_t m_time_now{GetTimeSeconds()};
501439

502440
public:
@@ -509,10 +447,8 @@ class NetinfoRequestHandler : public BaseRequestHandler
509447
uint8_t n{0};
510448
if (ParseUInt8(args.at(0), &n)) {
511449
m_details_level = std::min(n, MAX_DETAIL_LEVEL);
512-
} else if (args.at(0) == "help") {
513-
m_is_help_requested = true;
514450
} else {
515-
throw std::runtime_error(strprintf("invalid -netinfo argument: %s", args.at(0)));
451+
throw std::runtime_error(strprintf("invalid -netinfo argument: %s\nFor more information, run: dash-cli -netinfo help", args.at(0)));
516452
}
517453
}
518454
UniValue result(UniValue::VARR);
@@ -523,9 +459,6 @@ class NetinfoRequestHandler : public BaseRequestHandler
523459

524460
UniValue ProcessReply(const UniValue& batch_in) override
525461
{
526-
if (m_is_help_requested) {
527-
return JSONRPCReplyObj(NetinfoHelp(), NullUniValue, 1);
528-
}
529462
const std::vector<UniValue> batch{JSONRPCProcessBatchReply(batch_in)};
530463
if (!batch[ID_PEERINFO]["error"].isNull()) return batch[ID_PEERINFO];
531464
if (!batch[ID_NETWORKINFO]["error"].isNull()) return batch[ID_NETWORKINFO];
@@ -540,7 +473,6 @@ class NetinfoRequestHandler : public BaseRequestHandler
540473
const std::string network{peer["network"].get_str()};
541474
const int8_t network_id{NetworkStringToId(network)};
542475
if (network_id == UNKNOWN_NETWORK) continue;
543-
m_is_i2p_on |= (network_id == NET_I2P);
544476
const bool is_outbound{!peer["inbound"].get_bool()};
545477
const bool is_block_relay{peer["relaytxes"].isNull() ? false : !peer["relaytxes"].get_bool()};
546478
const std::string conn_type{peer["connection_type"].get_str()};
@@ -610,13 +542,14 @@ class NetinfoRequestHandler : public BaseRequestHandler
610542

611543
// Report peer connection totals by type.
612544
result += " ipv4 ipv6 onion";
613-
if (m_is_i2p_on) result += " i2p";
545+
const bool any_i2p_peers = m_counts.at(2).at(3); // false if total i2p peers count is 0, otherwise true
546+
if (any_i2p_peers) result += " i2p";
614547
result += " total block";
615548
if (m_manual_peers_count) result += " manual";
616549
const std::array rows{"in", "out", "total"};
617550
for (uint8_t i = 0; i < 3; ++i) {
618551
result += strprintf("\n%-5s %5i %5i %5i", rows.at(i), m_counts.at(i).at(0), m_counts.at(i).at(1), m_counts.at(i).at(2)); // ipv4/ipv6/onion peers counts
619-
if (m_is_i2p_on) result += strprintf(" %5i", m_counts.at(i).at(3)); // i2p peers count
552+
if (any_i2p_peers) result += strprintf(" %5i", m_counts.at(i).at(3)); // i2p peers count
620553
result += strprintf(" %5i", m_counts.at(i).at(m_networks.size())); // total peers count
621554
if (i == 1) { // the outbound row has two extra columns for block relay and manual peer counts
622555
result += strprintf(" %5i", m_block_relay_peers_count);
@@ -641,6 +574,64 @@ class NetinfoRequestHandler : public BaseRequestHandler
641574

642575
return JSONRPCReplyObj(UniValue{result}, NullUniValue, 1);
643576
}
577+
578+
const std::string m_help_doc{
579+
"-netinfo level|\"help\" \n\n"
580+
"Returns a network peer connections dashboard with information from the remote server.\n"
581+
"This human-readable interface will change regularly and is not intended to be a stable API.\n"
582+
"Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n"
583+
+ strprintf("An optional integer argument from 0 to %d can be passed for different peers listings; %d to 255 are parsed as %d.\n", MAX_DETAIL_LEVEL, MAX_DETAIL_LEVEL, MAX_DETAIL_LEVEL) +
584+
"Pass \"help\" to see this detailed help documentation.\n"
585+
"If more than one argument is passed, only the first one is read and parsed.\n"
586+
"Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n"
587+
"Arguments:\n"
588+
+ strprintf("1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n", MAX_DETAIL_LEVEL) +
589+
" 0 - Connection counts and local addresses\n"
590+
" 1 - Like 0 but with a peers listing (without address or version columns)\n"
591+
" 2 - Like 1 but with an address column\n"
592+
" 3 - Like 1 but with a version column\n"
593+
" 4 - Like 1 but with both address and version columns\n"
594+
"2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n"
595+
"Result:\n\n"
596+
+ strprintf("* The peers listing in levels 1-%d displays all of the peers sorted by direction and minimum ping time:\n\n", MAX_DETAIL_LEVEL) +
597+
" Column Description\n"
598+
" ------ -----------\n"
599+
" <-> Direction\n"
600+
" \"in\" - inbound connections are those initiated by the peer\n"
601+
" \"out\" - outbound connections are those initiated by us\n"
602+
" type Type of peer connection\n"
603+
" \"full\" - full relay, the default\n"
604+
" \"block\" - block relay; like full relay but does not relay transactions or addresses\n"
605+
" \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n"
606+
" \"feeler\" - short-lived connection for testing addresses\n"
607+
" \"addr\" - address fetch; short-lived connection for requesting addresses\n"
608+
" net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", or \"cjdns\")\n"
609+
" mping Minimum observed ping time, in milliseconds (ms)\n"
610+
" ping Last observed ping time, in milliseconds (ms)\n"
611+
" send Time since last message sent to the peer, in seconds\n"
612+
" recv Time since last message received from the peer, in seconds\n"
613+
" txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n"
614+
" blk Time since last novel block passing initial validity checks received from the peer, in minutes\n"
615+
" age Duration of connection to the peer, in minutes\n"
616+
" asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n"
617+
" peer selection (only displayed if the -asmap config option is set)\n"
618+
" id Peer index, in increasing order of peer connections since node startup\n"
619+
" address IP address and port of the peer\n"
620+
" version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n"
621+
"* The connection counts table displays the number of peers by direction, network, and the totals\n"
622+
" for each, as well as two special outbound columns for block relay peers and manual peers.\n\n"
623+
"* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n"
624+
"Examples:\n\n"
625+
"Connection counts and local addresses only\n"
626+
"> dash-cli -netinfo\n\n"
627+
"Compact peers listing\n"
628+
"> dash-cli -netinfo 1\n\n"
629+
"Full dashboard\n"
630+
+ strprintf("> dash-cli -netinfo %d\n\n", MAX_DETAIL_LEVEL) +
631+
"Full live dashboard, adjust --interval or --no-title as needed (Linux)\n"
632+
+ strprintf("> watch --interval 1 --no-title dash-cli -netinfo %d\n\n", MAX_DETAIL_LEVEL) +
633+
"See this help\n"
634+
"> dash-cli -netinfo help\n"};
644635
};
645636

646637
/** Process RPC generatetoaddress request. */
@@ -978,6 +969,10 @@ static int CommandLineRPC(int argc, char *argv[])
978969
if (gArgs.IsArgSet("-getinfo")) {
979970
rh.reset(new GetinfoRequestHandler());
980971
} else if (gArgs.GetBoolArg("-netinfo", false)) {
972+
if (!args.empty() && args.at(0) == "help") {
973+
tfm::format(std::cout, "%s\n", NetinfoRequestHandler().m_help_doc);
974+
return 0;
975+
}
981976
rh.reset(new NetinfoRequestHandler());
982977
} else if (gArgs.GetBoolArg("-generate", false)) {
983978
const UniValue getnewaddress{GetNewAddress()};

0 commit comments

Comments
 (0)