Merge bitcoin/bitcoin#25611: univalue: Avoid brittle, narrowing and verbose integral type confusions

fa23c19750 univalue: Avoid narrowing and verbose int constructors (MacroFake)
fa3a9a1e8d rpc: Select int-UniValue constructor for enum value in upgradewallet RPC (MacroFake)

Pull request description:

  As UniValue provides several constructors for integral types, the
  compiler is unable to select one if the passed type does not exactly
  match. This is unintuitive for developers and forces them to write
  verbose and brittle code. (Refer to `-Wnarrowing` compiler warning)

  For example, there are many places where an unsigned int is cast to a
  signed int. While the cast is safe in practice, it is still needlessly
  verbose and confusing as the value can never be negative. In fact it
  might even be unsafe if the unsigned value is large enough to map to a
  negative signed one.

  Fix this issue and other (minor) type issues.

ACKs for top commit:
  aureleoules:
    ACK fa23c19750.

Tree-SHA512: 7d99b5b90c7d8eed2e3448167255a59e817dd6b8fcfc1b17c69ddefd0db33d1bf4344fbcd8b7f8685b58182c0f572ab9ffa99467afa666ac21843df7ea645033
This commit is contained in:
fanquake 2022-07-25 15:01:16 +01:00
commit 73a0d6d0d4
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
3 changed files with 24 additions and 26 deletions

View file

@ -60,7 +60,7 @@ static RPCHelpMan getconnectioncount()
NodeContext& node = EnsureAnyNodeContext(request.context);
const CConnman& connman = EnsureConnman(node);
return (int)connman.GetNodeCount(ConnectionDirection::Both);
return connman.GetNodeCount(ConnectionDirection::Both);
},
};
}
@ -640,9 +640,9 @@ static RPCHelpMan getnetworkinfo()
obj.pushKV("timeoffset", GetTimeOffset());
if (node.connman) {
obj.pushKV("networkactive", node.connman->GetNetworkActive());
obj.pushKV("connections", (int)node.connman->GetNodeCount(ConnectionDirection::Both));
obj.pushKV("connections_in", (int)node.connman->GetNodeCount(ConnectionDirection::In));
obj.pushKV("connections_out", (int)node.connman->GetNodeCount(ConnectionDirection::Out));
obj.pushKV("connections", node.connman->GetNodeCount(ConnectionDirection::Both));
obj.pushKV("connections_in", node.connman->GetNodeCount(ConnectionDirection::In));
obj.pushKV("connections_out", node.connman->GetNodeCount(ConnectionDirection::Out));
}
obj.pushKV("networks", GetNetworksInfo());
obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));

View file

@ -24,27 +24,25 @@ public:
typ = initialType;
val = initialStr;
}
UniValue(uint64_t val_) {
setInt(val_);
}
UniValue(int64_t val_) {
setInt(val_);
}
UniValue(bool val_) {
setBool(val_);
}
UniValue(int val_) {
setInt(val_);
}
UniValue(double val_) {
setFloat(val_);
}
UniValue(const std::string& val_) {
setStr(val_);
}
UniValue(const char *val_) {
std::string s(val_);
setStr(s);
template <typename Ref, typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
std::enable_if_t<std::is_floating_point_v<T> || // setFloat
std::is_same_v<bool, T> || // setBool
std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
std::is_constructible_v<std::string, T>, // setStr
bool> = true>
UniValue(Ref&& val)
{
if constexpr (std::is_floating_point_v<T>) {
setFloat(val);
} else if constexpr (std::is_same_v<bool, T>) {
setBool(val);
} else if constexpr (std::is_signed_v<T>) {
setInt(int64_t{val});
} else if constexpr (std::is_unsigned_v<T>) {
setInt(uint64_t{val});
} else {
setStr(std::string{std::forward<Ref>(val)});
}
}
void clear();

View file

@ -532,7 +532,7 @@ static RPCHelpMan upgradewallet()
"\nUpgrade the wallet. Upgrades to the latest version if no version number is specified.\n"
"New keys may be generated and a new wallet backup will need to be made.",
{
{"version", RPCArg::Type::NUM, RPCArg::Default{FEATURE_LATEST}, "The version number to upgrade to. Default is the latest wallet version."}
{"version", RPCArg::Type::NUM, RPCArg::Default{int{FEATURE_LATEST}}, "The version number to upgrade to. Default is the latest wallet version."}
},
RPCResult{
RPCResult::Type::OBJ, "", "",