Repository: bitcoin/bitcoin
File: src/bitcoin-cli.cpp (C++)

Code before:
    result_string += strprintf("Proxies: %s\n", formatted_proxies.empty() ? "n/a" : Join(formatted_proxies, ", "));

    result_string += strprintf("Min tx relay fee rate (%s/kvB): %s\n\n", CURRENCY_UNIT, result["relayfee"].getValStr());

    if (!result["has_wallet"].isNull()) {
        const std::string walletname = result["walletname"].getValStr();
        result_string += strprintf("%sWallet: %s%s\n", MAGENTA, walletname.empty() ? "\"\"" : walletname, RESET);

        result_string += strprintf("Keypool size: %s\n", result["keypoolsize"].getValStr());
        if (!result["unlocked_until"].isNull()) {
            result_string += strprintf("Unlocked until: %s\n", result["unlocked_until"].getValStr());
        }
        result_string += strprintf("Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n", CURRENCY_UNIT, result["paytxfee"].getValStr());
    }
    if (!result["balance"].isNull()) {
        result_string += strprintf("%sBalance:%s %s\n\n", CYAN, RESET, result["balance"].getValStr());
    }

    if (!result["balances"].isNull()) {
        result_string += strprintf("%sBalances%s\n", CYAN, RESET);

        size_t max_balance_length{10};

        for (const std::string& wallet : result["balances"].getKeys()) {
            max_balance_length = std::max(result["balances"][wallet].getValStr().length(), max_balance_length);
        }

        for (const std::string& wallet : result["balances"].getKeys()) {
            result_string += strprintf("%*s %s\n",
                                       max_balance_length,
                                       result["balances"][wallet].getValStr(),
                                       wallet.empty() ? "\"\"" : wallet);
        }
        result_string += "\n";
    }

    const std::string warnings{result["warnings"].getValStr()};
    result_string += strprintf("%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ? "(none)" : warnings);

    result.setStr(result_string);
}

/**
 * Call RPC getnewaddress.
 * @returns getnewaddress response as a UniValue object.
 */
static UniValue GetNewAddress()
{
    std::optional<std::string> wallet_name{};
    if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");
    DefaultRequestHandler rh;

Review comment (performance):
https://github.com/bitcoin/bitcoin/commit/fa48d460334beef43fa73455aa9e30971d33c1b2 This seems like a lot of code for what could be 2 lines instead, and you could make the commands data structure an `constexpr` array constant and have it run in O(n) instead of O(log n) (and order the commands by probable frequency of invocation). The resulting code is self-explanatory, so could drop the comments too.

<details><summary>Suggested diff</summary><p>

```diff
@@ -53,6 +53,7 @@ using CliClock = std::chrono::system_clock;
 
+constexpr std::array<std::string_view, 4> CLI_COMMANDS{"-netinfo", "-getinfo", "-addrinfo", "-generate"};
 static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";

@@ -1105,20 +1106,6 @@ static UniValue GetNewAddress()
 
-/**
- * IsExclusivelyCliCommand checks if a string is a cli-command that needs to run exclusively
- * @param[in] cli_command The string to check if it is a cli-command that needs to run exclusively.
- * @returns true if cli_command is included in the set of the exclusively_commands.
- */
-bool IsExclusivelyCliCommand(const std::string_view cli_command)
-{
-    // Initialize set with cli-commands that run exclusively
-    const std::set<std::string_view> exclusively_commands{"-generate", "-netinfo", "-addrinfo", "-getinfo"};
-
-    // return if element was found or not
-    return (exclusively_commands.find(cli_command) != exclusively_commands.end());
-}
-

@@ -1131,38 +1118,26 @@ static void ValidateCliCommand(int argc, char *argv[])
-            // Check if it's a cli-command that runs exclusively e.g. a user could run:
-            // "bitcoin-cli -regtest -generate -netinfo -addrinfo -getinfo" but it's confusing,
-            // only the last one will be executed so we make sure the user specify only one
-            if (IsExclusivelyCliCommand(command)) {
+            if (std::find(std::begin(CLI_COMMANDS), std::end(CLI_COMMANDS), command) != std::end(CLI_COMMANDS)) {
```
</p></details>


Code after:
    }
    result_string += strprintf("Proxies: %s\n", formatted_proxies.empty() ? "n/a" : Join(formatted_proxies, ", "));

    result_string += strprintf("Min tx relay fee rate (%s/kvB): %s\n\n", CURRENCY_UNIT, result["relayfee"].getValStr());

    if (!result["has_wallet"].isNull()) {
        const std::string walletname = result["walletname"].getValStr();
        result_string += strprintf("%sWallet: %s%s\n", MAGENTA, walletname.empty() ? "\"\"" : walletname, RESET);

        result_string += strprintf("Keypool size: %s\n", result["keypoolsize"].getValStr());
        if (!result["unlocked_until"].isNull()) {
            result_string += strprintf("Unlocked until: %s\n", result["unlocked_until"].getValStr());
        }
        result_string += strprintf("Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n", CURRENCY_UNIT, result["paytxfee"].getValStr());
    }
    if (!result["balance"].isNull()) {
        result_string += strprintf("%sBalance:%s %s\n\n", CYAN, RESET, result["balance"].getValStr());
    }

    if (!result["balances"].isNull()) {
        result_string += strprintf("%sBalances%s\n", CYAN, RESET);

        size_t max_balance_length{10};

        for (const std::string& wallet : result["balances"].getKeys()) {
            max_balance_length = std::max(result["balances"][wallet].getValStr().length(), max_balance_length);
        }

        for (const std::string& wallet : result["balances"].getKeys()) {
            result_string += strprintf("%*s %s\n",
                                       max_balance_length,
                                       result["balances"][wallet].getValStr(),
                                       wallet.empty() ? "\"\"" : wallet);
        }
        result_string += "\n";
    }

    const std::string warnings{result["warnings"].getValStr()};
    result_string += strprintf("%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ? "(none)" : warnings);

    result.setStr(result_string);
}

/**
 * Call RPC getnewaddress.
 * @returns getnewaddress response as a UniValue object.
 */
static UniValue GetNewAddress()
{
    std::optional<std::string> wallet_name{};
    if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");