Repository: bitcoin/bitcoin
File: src/rpc/util.cpp (C++)

Code before:
{
    if (!value.isNum() && !value.isStr())
        throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
    CAmount amount;
    if (!ParseFixedPoint(value.getValStr(), decimals, &amount))
        throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
    if (!MoneyRange(amount))
        throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
    return amount;
}

CFeeRate ParseFeeRate(const UniValue& json)
{
    CAmount val{AmountFromValue(json)};
    if (val >= COIN) throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee rates larger than or equal to 1BTC/kvB are not accepted");
    return CFeeRate{val};
}

uint256 ParseHashV(const UniValue& v, std::string_view name)
{
    const std::string& strHex(v.get_str());
    if (64 != strHex.length())
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", name, 64, strHex.length(), strHex));
    if (!IsHex(strHex)) // Note: IsHex("") is false
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be hexadecimal string (not '%s')", name, strHex));
    return uint256S(strHex);
}
uint256 ParseHashO(const UniValue& o, std::string_view strKey)
{
    return ParseHashV(o.find_value(strKey), strKey);
}
std::vector<unsigned char> ParseHexV(const UniValue& v, std::string_view name)
{
    std::string strHex;
    if (v.isStr())
        strHex = v.get_str();
    if (!IsHex(strHex))
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be hexadecimal string (not '%s')", name, strHex));
    return ParseHex(strHex);
}
std::vector<unsigned char> ParseHexO(const UniValue& o, std::string_view strKey)
{
    return ParseHexV(o.find_value(strKey), strKey);
}

namespace {

/**
 * Quote an argument for shell.
 *
 * @note This is intended for help, not for security-sensitive purposes.

Review comment (suggestion):
Nit1: consider narrowing the scope of expected:
Nit2: usually we compare the actual against the expected (switched the order):
```suggestion
    if (auto expected_len{uint256::size() * 2}; strHex.length() != expected_len) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", name, expected_len, strHex.length(), strHex));
    }
```

No strong feelings either way, feel free to ignore if you don't like it

Code after:
CAmount AmountFromValue(const UniValue& value, int decimals)
{
    if (!value.isNum() && !value.isStr())
        throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
    CAmount amount;
    if (!ParseFixedPoint(value.getValStr(), decimals, &amount))
        throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
    if (!MoneyRange(amount))
        throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
    return amount;
}

CFeeRate ParseFeeRate(const UniValue& json)
{
    CAmount val{AmountFromValue(json)};
    if (val >= COIN) throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee rates larger than or equal to 1BTC/kvB are not accepted");
    return CFeeRate{val};
}

uint256 ParseHashV(const UniValue& v, std::string_view name)
{
    const std::string& strHex(v.get_str());
    if (auto rv{uint256::FromHex(strHex)}) return *rv;
    if (auto expected_len{uint256::size() * 2}; strHex.length() != expected_len) {
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", name, expected_len, strHex.length(), strHex));
    }
    throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be hexadecimal string (not '%s')", name, strHex));
}
uint256 ParseHashO(const UniValue& o, std::string_view strKey)
{
    return ParseHashV(o.find_value(strKey), strKey);
}
std::vector<unsigned char> ParseHexV(const UniValue& v, std::string_view name)
{
    std::string strHex;
    if (v.isStr())
        strHex = v.get_str();
    if (!IsHex(strHex))
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be hexadecimal string (not '%s')", name, strHex));
    return ParseHex(strHex);
}
std::vector<unsigned char> ParseHexO(const UniValue& o, std::string_view strKey)
{
    return ParseHexV(o.find_value(strKey), strKey);
}

namespace {

/**
 * Quote an argument for shell.
 *